mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			60 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python3
 | |
| 
 | |
| import argparse
 | |
| import shutil
 | |
| import subprocess
 | |
| import sys
 | |
| from functools import cmp_to_key
 | |
| from pathlib import Path
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     parser = argparse.ArgumentParser(
 | |
|                  epilog=__doc__,
 | |
|                  formatter_class=argparse.RawDescriptionHelpFormatter)
 | |
|     parser.add_argument('kernel', help='kernel binary location')
 | |
|     parser.add_argument('-n', '--nm', required=True, help='path to nm')
 | |
|     parser.add_argument('-o', '--objcopy', required=True, help='path to objcopy')
 | |
|     args = parser.parse_args()
 | |
| 
 | |
|     kernel_path = Path(args.kernel)
 | |
|     binary_directory = kernel_path.parent
 | |
| 
 | |
|     # Write out kernel.map, which contains kernel symbols and their addresses
 | |
|     symbols = subprocess.check_output([args.nm, '-C', '-n', str(kernel_path)])
 | |
|     if not symbols:
 | |
|         print(f"Unable to dump symbols from {kernel_path}", file=sys.stderr)
 | |
|         return 1
 | |
| 
 | |
|     def filter_symbol(s):
 | |
|         return s and not (".Lubsan_data" in s or s.split()[1] == "a")
 | |
| 
 | |
|     symbols = filter(filter_symbol, symbols.decode().split('\n'))
 | |
|     symbols = list(set(symbols))
 | |
| 
 | |
|     def sort_symbols(s1, s2):
 | |
|         return int(s1.split()[0], base=16) - int(s2.split()[0], base=16)
 | |
|     symbols = sorted(symbols, key=cmp_to_key(sort_symbols))
 | |
| 
 | |
|     kernel_map = binary_directory / "kernel.map"
 | |
|     with open(kernel_map, 'w') as out:
 | |
|         out.write(f'{len(symbols):#x}\n')
 | |
|         out.write('\n'.join(symbols))
 | |
|         out.write('\0')
 | |
| 
 | |
|     kernel_final = binary_directory / "Kernel"
 | |
| 
 | |
|     shutil.copyfile(kernel_path, kernel_final)
 | |
| 
 | |
|     kernel_final = str(kernel_final)
 | |
| 
 | |
|     subprocess.check_call([args.objcopy, "--update-section", f".ksyms={kernel_map}", kernel_final])
 | |
|     subprocess.check_call([args.objcopy, "--only-keep-debug", kernel_final, kernel_final + ".debug"])
 | |
|     subprocess.check_call([args.objcopy, "--strip-debug", kernel_final])
 | |
|     subprocess.check_call([args.objcopy, f"--add-gnu-debuglink={kernel_final}.debug", kernel_final])
 | |
| 
 | |
|     return 0
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     sys.exit(main())
 | 
