77# portable way to do that. Therefore we pass the linker path and all the command
88# line parameters to this script and call the linker directly.
99
10+ import os
1011import argparse
1112import subprocess
1213from elftools .elf .elffile import ELFFile
14+ import re
1315
1416args = None
1517def parse_args ():
@@ -33,21 +35,53 @@ def main():
3335 elf = ELFFile (open (args .file , 'rb' ))
3436
3537 text_addr = int (args .text_addr , 0 )
38+ p = re .compile ('(^lib|\.so$)' )
39+ module = p .sub ('' , args .file )
3640
37- text_offset = elf .get_section_by_name ('.text' ).header .sh_offset
38- rodata_offset = elf .get_section_by_name ('.rodata' ).header .sh_offset
39- data_offset = elf .get_section_by_name ('.data' ).header .sh_offset
41+ if elf .get_section_by_name ('.rodata' ) != None :
42+ # A shared object type image, it contains segments
43+ sections = ['.text' , '.rodata' , '.data' , '.bss' ]
44+ alignment = [0x1000 , 0x1000 , 0x10 , 0x1000 ]
45+ else :
46+ # A relocatable object, need to handle all sections separately
47+ sections = ['.text' ,
48+ f'._log_const.static.log_const_{ module } _' ,
49+ '.static_uuids' , '.z_init_APPLICATION90_0_' , '.module' ,
50+ '.mod_buildinfo' , '.data' , '.trace_ctx' , '.bss' ]
51+ alignment = [0x1000 , 0x1000 , 0x0 , 0x0 , 0x0 , 0x0 , 0x10 , 0x0 , 0x1000 ]
4052
41- upper = rodata_offset - text_offset + text_addr + 0xfff
42- rodata_addr = upper - (upper % 0x1000 )
53+ last_increment = 0
4354
44- upper = data_offset - rodata_offset + rodata_addr + 0xf
45- data_addr = upper - (upper % 0x10 )
55+ command = [args .command ]
56+
57+ for i in range (len (sections )):
58+ try :
59+ offset = elf .get_section_by_name (sections [i ]).header .sh_offset
60+ size = elf .get_section_by_name (sections [i ]).header .sh_size
61+ except :
62+ continue
63+
64+ if last_increment == 0 :
65+ # first section must be .text and it must be successful
66+ if i != 0 or sections [i ] != '.text' :
67+ break
68+
69+ addresse = text_addr
70+ elif alignment [i ] != 0 :
71+ upper = offset + last_increment + alignment [i ] - 1
72+ addresse = upper - (upper % alignment [i ])
73+ else :
74+ addresse = offset + last_increment
75+
76+ last_increment = addresse - offset
77+
78+ if sections [i ] == '.text' :
79+ command .append (f'-Wl,-Ttext=0x{ text_addr :x} ' )
80+ elif sections [i ] == '.data' :
81+ command .append (f'-Wl,-Tdata=0x{ addresse :x} ' )
82+ else :
83+ command .append (f'-Wl,--section-start={ sections [i ]} =0x{ addresse :x} ' )
4684
47- command = [args .command ,
48- f'-Wl,-Ttext=0x{ text_addr :x} ' ,
49- f'-Wl,--section-start=.rodata=0x{ rodata_addr :x} ' ,
50- f'-Wl,-Tdata=0x{ data_addr :x} ' ]
5185 command .extend (args .params )
5286
5387 subprocess .run (command )
0 commit comments