~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/generate_builtin_ranges.awk

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/generate_builtin_ranges.awk (Version linux-6.12-rc7) and /scripts/generate_builtin_ranges.awk (Version linux-6.7.12)


  1 #!/usr/bin/gawk -f                                
  2 # SPDX-License-Identifier: GPL-2.0                
  3 # generate_builtin_ranges.awk: Generate addres    
  4 # Written by Kris Van Hees <kris.van.hees@oracl    
  5 #                                                 
  6 # Usage: generate_builtin_ranges.awk modules.b    
  7 #               vmlinux.o.map > modules.builti    
  8 #                                                 
  9                                                   
 10 # Return the module name(s) (if any) associate    
 11 #                                                 
 12 # If we have seen this object before, return i    
 13 # Otherwise, retrieve it from the correspondin    
 14 #                                                 
 15 function get_module_info(fn, mod, obj, s) {       
 16         if (fn in omod)                           
 17                 return omod[fn];                  
 18                                                   
 19         if (match(fn, /\/[^/]+$/) == 0)           
 20                 return "";                        
 21                                                   
 22         obj = fn;                                 
 23         mod = "";                                 
 24         fn = substr(fn, 1, RSTART) "." substr(    
 25         if (getline s <fn == 1) {                 
 26                 if (match(s, /DKBUILD_MODFILE=    
 27                         mod = substr(s, RSTART    
 28                         gsub(/['"]/, "", mod);    
 29                 } else if (match(s, /RUST_MODF    
 30                         mod = substr(s, RSTART    
 31         }                                         
 32         close(fn);                                
 33                                                   
 34         # A single module (common case) also r    
 35         # of a module.  Some of those objects     
 36         # name (e.g. core).  We check the asso    
 37         # they do not match, the object is not    
 38         if (mod !~ / /) {                         
 39                 if (!(mod in mods))               
 40                         mod = "";                 
 41         }                                         
 42                                                   
 43         gsub(/([^/ ]*\/)+/, "", mod);             
 44         gsub(/-/, "_", mod);                      
 45                                                   
 46         # At this point, mod is a single (vali    
 47         # module names (that do not need valid    
 48         omod[obj] = mod;                          
 49                                                   
 50         return mod;                               
 51 }                                                 
 52                                                   
 53 # Update the ranges entry for the given module    
 54 #                                                 
 55 # We use a modified absolute start address (so    
 56 # may need to insert an anchor record later th    
 57 # section data, and the first module may very     
 58 # So, we use (addr << 1) + 1 to allow a possib    
 59 # (addr << 1).  This is safe because the index    
 60 # before writing them out.                        
 61 #                                                 
 62 function update_entry(osect, mod, soff, eoff,     
 63         sect = sect_in[osect];                    
 64         idx = sprintf("%016x", (soff + sect_ba    
 65         entries[idx] = sprintf("%s %08x-%08x %    
 66         count[sect]++;                            
 67 }                                                 
 68                                                   
 69 # (1) Build a lookup map of built-in module na    
 70 #                                                 
 71 # The first file argument is used as input (mo    
 72 #                                                 
 73 # Lines will be like:                             
 74 #       kernel/crypto/lzo-rle.ko                  
 75 # and we record the object name "crypto/lzo-rl    
 76 #                                                 
 77 ARGIND == 1 {                                     
 78         sub(/kernel\//, "");                      
 79         sub(/\.ko$/, "");                         
 80                                                   
 81         mods[$1] = 1;                             
 82         next;                                     
 83 }                                                 
 84                                                   
 85 # (2) Collect address information for each sec    
 86 #                                                 
 87 # The second file argument is used as input (v    
 88 #                                                 
 89 # We collect the base address of the section i    
 90 # in the section into offset values.              
 91 #                                                 
 92 # We collect the address of the anchor (or fir    
 93 # is no explicit anchor) to allow users of the    
 94 # ranges based on the actual load address of t    
 95 #                                                 
 96 # We collect the start address of any sub-sect    
 97 # level section being processed).  This is nee    
 98 # done using vmlinux.a because then the list o    
 99 # section is to be obtained from vmlinux.o.map    
100 # is recorded here, to be used as an addend wh    
101 # later.                                          
102 #                                                 
103                                                   
104 # Both GNU ld and LLVM lld linker map format a    
105 # lld linker map records into equivalent GNU l    
106 #                                                 
107 # The first record of the vmlinux.map file pro    
108 # which format we are dealing with.               
109 #                                                 
110 ARGIND == 2 && FNR == 1 && NF == 7 && $1 == "V    
111         map_is_lld = 1;                           
112         if (dbg)                                  
113                 printf "NOTE: %s uses LLVM lld    
114         next;                                     
115 }                                                 
116                                                   
117 # (LLD) Convert a section record fronm lld for    
118 #                                                 
119 # lld: ffffffff82c00000          2c00000   249    
120 #  ->                                             
121 # ld:  .data           0xffffffff82c00000   0x    
122 #                                                 
123 ARGIND == 2 && map_is_lld && NF == 5 && /[0-9]    
124         $0 = $5 " 0x"$1 " 0x"$3 " load address    
125 }                                                 
126                                                   
127 # (LLD) Convert an anchor record from lld form    
128 #                                                 
129 # lld: ffffffff81000000          1000000          
130 #  ->                                             
131 # ld:                  0xffffffff81000000         
132 #                                                 
133 ARGIND == 2 && map_is_lld && !anchor && NF ==     
134         $0 = "  0x"$1 " " $5 " = .";              
135 }                                                 
136                                                   
137 # (LLD) Convert an object record from lld form    
138 #                                                 
139 # lld:            11480            11480     1    
140 #  ->                                             
141 # ld:   .text          0x0000000000011480         
142 #                                                 
143 ARGIND == 2 && map_is_lld && NF == 5 && $5 ~ /    
144         gsub(/\)/, "");                           
145         sub(/ vmlinux\.a\(/, " ");                
146         sub(/:\(/, " ");                          
147         $0 = " "$6 " 0x"$1 " 0x"$3 " " $5;        
148 }                                                 
149                                                   
150 # (LLD) Convert a symbol record from lld forma    
151 #                                                 
152 # We only care about these while processing a     
153 # been determined yet.                            
154 #                                                 
155 # lld: ffffffff82a859a4          2a859a4          
156 #  ->                                             
157 # ld:                  0xffffffff82a859a4         
158 #                                                 
159 ARGIND == 2 && map_is_lld && sect && !anchor &    
160         $0 = "  0x"$1 " " $5;                     
161 }                                                 
162                                                   
163 # (LLD) We do not need any other ldd linker ma    
164 #                                                 
165 ARGIND == 2 && map_is_lld && /^[0-9a-f]{16} /     
166         next;                                     
167 }                                                 
168                                                   
169 # (LD) Section records with just the section n    
170 #      need to have the next line pulled in to    
171 #      loadable section.  If it is, the next l    
172 #      as first and second items.                 
173 #                                                 
174 ARGIND == 2 && !map_is_lld && NF == 1 && /^[^     
175         s = $0;                                   
176         getline;                                  
177         if ($1 !~ /^0x/ || $2 !~ /^0x/)           
178                 next;                             
179                                                   
180         $0 = s " " $0;                            
181 }                                                 
182                                                   
183 # (LD) Object records with just the section na    
184 #      section name for which the remainder of    
185 #      next line.                                 
186 #                                                 
187 # (This is also needed for vmlinux.o.map, when    
188 #                                                 
189 ARGIND >= 2 && !map_is_lld && NF == 1 && /^ [^    
190         s = $0;                                   
191         getline;                                  
192         $0 = s " " $0;                            
193 }                                                 
194                                                   
195 # Beginning a new section - done with the prev    
196 #                                                 
197 ARGIND == 2 && /^[^ ]/ {                          
198         sect = 0;                                 
199 }                                                 
200                                                   
201 # Process a loadable section (we only care abo    
202 #                                                 
203 # Record the section name and its base address    
204 # We also record the raw (non-stripped) addres    
205 # be used to identify an anchor record.           
206 #                                                 
207 # Note:                                           
208 # Since some AWK implementations cannot handle    
209 # first 4 hex digits from the address.  This i    
210 # is not large enough for addresses to extend     
211 # to strip off is stored in addr_prefix as a r    
212 # perform a simple substitution to do the addr    
213 #                                                 
214 ARGIND == 2 && /^\./ {                            
215         # Explicitly ignore a few sections tha    
216         if ($1 ~ /^\.orc_/ || $1 ~ /_sites$/ |    
217                 next;                             
218                                                   
219         # Sections with a 0-address can be ign    
220         if ($2 ~ /^0x0+$/)                        
221                 next;                             
222                                                   
223         raw_addr = $2;                            
224         addr_prefix = "^" substr($2, 1, 6);       
225         base = $2;                                
226         sub(addr_prefix, "0x", base);             
227         base = strtonum(base);                    
228         sect = $1;                                
229         anchor = 0;                               
230         sect_base[sect] = base;                   
231         sect_size[sect] = strtonum($3);           
232                                                   
233         if (dbg)                                  
234                 printf "[%s] BASE   %016x\n",     
235                                                   
236         next;                                     
237 }                                                 
238                                                   
239 # If we are not in a section we care about, we    
240 #                                                 
241 ARGIND == 2 && !sect {                            
242         next;                                     
243 }                                                 
244                                                   
245 # Record the first anchor symbol for the curre    
246 #                                                 
247 # An anchor record for the section bears the s    
248 # record.                                         
249 #                                                 
250 ARGIND == 2 && !anchor && NF == 4 && raw_addr     
251         anchor = sprintf("%s %08x-%08x = %s",     
252         sect_anchor[sect] = anchor;               
253                                                   
254         if (dbg)                                  
255                 printf "[%s] ANCHOR %016x = %s    
256                                                   
257         next;                                     
258 }                                                 
259                                                   
260 # If no anchor record was found for the curren    
261 # in the section as anchor.                       
262 #                                                 
263 ARGIND == 2 && !anchor && NF == 2 && $1 ~ /^0x    
264         addr = $1;                                
265         sub(addr_prefix, "0x", addr);             
266         addr = strtonum(addr) - base;             
267         anchor = sprintf("%s %08x-%08x = %s",     
268         sect_anchor[sect] = anchor;               
269                                                   
270         if (dbg)                                  
271                 printf "[%s] ANCHOR %016x = %s    
272                                                   
273         next;                                     
274 }                                                 
275                                                   
276 # The first occurrence of a section name in an    
277 # addend (often 0) for that section.  This inf    
278 # sections that get combined in the final link    
279 # getting included at the start of .text).        
280 #                                                 
281 # If the section does not have a base yet, use    
282 # section.                                        
283 #                                                 
284 ARGIND == 2 && sect && NF == 4 && /^ [^ \*]/ &    
285         if (!($1 in sect_base)) {                 
286                 sect_base[$1] = base;             
287                                                   
288                 if (dbg)                          
289                         printf "[%s] BASE   %0    
290         }                                         
291                                                   
292         addr = $2;                                
293         sub(addr_prefix, "0x", addr);             
294         addr = strtonum(addr);                    
295         sect_addend[$1] = addr - sect_base[$1]    
296         sect_in[$1] = sect;                       
297                                                   
298         if (dbg)                                  
299                 printf "[%s] ADDEND %016x - %0    
300                                                   
301         # If the object is vmlinux.o then we w    
302         # actual offsets of objects.              
303         if ($4 == "vmlinux.o")                    
304                 need_o_map = 1;                   
305 }                                                 
306                                                   
307 # (3) Collect offset ranges (relative to the s    
308 # modules.                                        
309 #                                                 
310 # If the final link was done using the actual     
311 # the information we need (see section (3a)).     
312 # If linking was done using vmlinux.a as inter    
313 # vmlinux.o.map (see section (3b)).               
314                                                   
315 # (3a) Determine offset range info using vmlin    
316 #                                                 
317 # Since we are already processing vmlinux.map,    
318 # being processed is already known.  If we do     
319 # we do not need to process records for it.       
320 #                                                 
321 # Given the object name, we determine the modu    
322 # object is associated with.                      
323 #                                                 
324 # If we were already processing objects for a     
325 #  - If the current object belongs to the same    
326 #    to include the current object.               
327 #  - Otherwise, ensure that the end offset of     
328 #                                                 
329 # If the current object does not belong to a b    
330 #                                                 
331 # If it does, we add a new built-in module off    
332 #                                                 
333 ARGIND == 2 && !need_o_map && /^ [^ ]/ && NF =    
334         if (!(sect in sect_base))                 
335                 next;                             
336                                                   
337         # Turn the address into an offset from    
338         soff = $2;                                
339         sub(addr_prefix, "0x", soff);             
340         soff = strtonum(soff) - sect_base[sect    
341         eoff = soff + strtonum($3);               
342                                                   
343         # Determine which (if any) built-in mo    
344         mod = get_module_info($4);                
345                                                   
346         # If we are processing a built-in modu    
347         #   - If the current object is within     
348         #     entry by extending the range and    
349         #   - Otherwise:                          
350         #       + If we are still processing w    
351         #         validate the end offset agai    
352         #         current object (e.g. .rodata    
353         #         listed with an incorrect siz    
354         #       + Otherwise, we validate the e    
355         #         size                            
356         if (mod_name) {                           
357                 if (mod == mod_name) {            
358                         mod_eoff = eoff;          
359                         update_entry(mod_sect,    
360                                                   
361                         next;                     
362                 } else if (sect == sect_in[mod    
363                         if (mod_eoff > soff)      
364                                 update_entry(m    
365                 } else {                          
366                         v = sect_size[sect_in[    
367                         if (mod_eoff > v)         
368                                 update_entry(m    
369                 }                                 
370         }                                         
371                                                   
372         mod_name = mod;                           
373                                                   
374         # If we encountered an object that is     
375         # do not need to record any data.         
376         if (!mod)                                 
377                 next;                             
378                                                   
379         # At this point, we encountered the st    
380         mod_name = mod;                           
381         mod_soff = soff;                          
382         mod_eoff = eoff;                          
383         mod_sect = $1;                            
384         update_entry($1, mod, soff, mod_eoff);    
385                                                   
386         next;                                     
387 }                                                 
388                                                   
389 # If we do not need to parse the vmlinux.o.map    
390 #                                                 
391 ARGIND == 3 && !need_o_map {                      
392         if (dbg)                                  
393                 printf "Note: %s is not needed    
394         exit;                                     
395 }                                                 
396                                                   
397 # (3) Collect offset ranges (relative to the s    
398 # modules.                                        
399 #                                                 
400                                                   
401 # (LLD) Convert an object record from lld form    
402 #                                                 
403 ARGIND == 3 && map_is_lld && NF == 5 && $5 ~ /    
404         gsub(/\)/, "");                           
405         sub(/:\(/, " ");                          
406                                                   
407         sect = $6;                                
408         if (!(sect in sect_addend))               
409                 next;                             
410                                                   
411         sub(/ vmlinux\.a\(/, " ");                
412         $0 = " "sect " 0x"$1 " 0x"$3 " " $5;      
413 }                                                 
414                                                   
415 # (3b) Determine offset range info using vmlin    
416 #                                                 
417 # If we do not know an addend for the object's    
418 # anything within that section.                   
419 #                                                 
420 # Determine the top-level section that the obj    
421 # during the final link.  This is the section     
422 # associated with for this object.                
423 #                                                 
424 # The remainder of the processing of the curre    
425 # procedure outlined in (3a).                     
426 #                                                 
427 ARGIND == 3 && /^ [^ ]/ && NF == 4 && $3 != "0    
428         osect = $1;                               
429         if (!(osect in sect_addend))              
430                 next;                             
431                                                   
432         # We need to work with the main sectio    
433         sect = sect_in[osect];                    
434                                                   
435         # Turn the address into an offset from    
436         soff = $2;                                
437         sub(addr_prefix, "0x", soff);             
438         soff = strtonum(soff) + sect_addend[os    
439         eoff = soff + strtonum($3);               
440                                                   
441         # Determine which (if any) built-in mo    
442         mod = get_module_info($4);                
443                                                   
444         # If we are processing a built-in modu    
445         #   - If the current object is within     
446         #     entry by extending the range and    
447         #   - Otherwise:                          
448         #       + If we are still processing w    
449         #         validate the end offset agai    
450         #         current object (e.g. .rodata    
451         #         listed with an incorrect siz    
452         #       + Otherwise, we validate the e    
453         #         size                            
454         if (mod_name) {                           
455                 if (mod == mod_name) {            
456                         mod_eoff = eoff;          
457                         update_entry(mod_sect,    
458                                                   
459                         next;                     
460                 } else if (sect == sect_in[mod    
461                         if (mod_eoff > soff)      
462                                 update_entry(m    
463                 } else {                          
464                         v = sect_size[sect_in[    
465                         if (mod_eoff > v)         
466                                 update_entry(m    
467                 }                                 
468         }                                         
469                                                   
470         mod_name = mod;                           
471                                                   
472         # If we encountered an object that is     
473         # do not need to record any data.         
474         if (!mod)                                 
475                 next;                             
476                                                   
477         # At this point, we encountered the st    
478         mod_name = mod;                           
479         mod_soff = soff;                          
480         mod_eoff = eoff;                          
481         mod_sect = osect;                         
482         update_entry(osect, mod, soff, mod_eof    
483                                                   
484         next;                                     
485 }                                                 
486                                                   
487 # (4) Generate the output.                        
488 #                                                 
489 # Anchor records are added for each section th    
490 # records.  They are added at an adjusted sect    
491 # ensure they come first in the second records    
492 # more information).                              
493 #                                                 
494 # All entries are sorted by (adjusted) address    
495 # parsed in strict ascending address order.       
496 #                                                 
497 END {                                             
498         for (sect in count) {                     
499                 if (sect in sect_anchor) {        
500                         idx = sprintf("%016x",    
501                         entries[idx] = sect_an    
502                 }                                 
503         }                                         
504                                                   
505         n = asorti(entries, indices);             
506         for (i = 1; i <= n; i++)                  
507                 print entries[indices[i]];        
508 }                                                 
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php