This improves the portability of the linker script and allows lld to link rom.o
Dot assignment inside an output section has an inconsistent behavior which makes lld difficult to implement. See https://bugs.llvm.org/show_bug.cgi?id=43083
Dropping `. =` turns out to be beneficial to older GNU ld as well because we can delete an ld check detecting "cannot move location counter backwards".
-- Changes v2 -> v3 * Add `first` to avoid overloading `location` * Delete startsym from the parameters
Signed-off-by: Fangrui Song maskray@google.com --- scripts/layoutrom.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index caed387..caa182a 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -331,19 +331,25 @@ def outSections(sections, useseg=0): return out
# Write LD script includes for the given sections using relative offsets -def outRelSections(sections, startsym, useseg=0): +def outRelSections(sections, useseg=0): sections = [(section.finalloc, section) for section in sections if section.finalloc is not None] sections.sort(key=operator.itemgetter(0)) out = "" + first = True for addr, section in sections: loc = section.finalloc if useseg: loc = section.finalsegloc - out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym) + if first: + out += ". += 0x%x - _reloc_init_end ;\n" % (loc,) + first = False + elif location != loc: + out += ". += 0x%x ;\n" % (loc-location,) if section.name in ('.rodata.str1.1', '.rodata'): out += "_rodata%s = . ;\n" % (section.fileid,) out += "*%s.*(%s)\n" % (section.fileid, section.name) + location = loc + section.size return out
# Build linker script output for a list of relocations. @@ -444,7 +450,7 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): sec32all_start, multiboot_header, relocstr, - outRelSections(li.sections, 'code32flat_start')) + outRelSections(li.sections)) out = COMMONHEADER + out + COMMONTRAILER + """ ENTRY(%s) PHDRS