make --debugout output to a separate file in the same run, have debugout ELFs contain proper interp and dyn segments without changing the output file layout

This commit is contained in:
PoroCYon 2020-08-24 01:20:41 +02:00
parent 10181a24b5
commit 60d51bbc3b
4 changed files with 26 additions and 22 deletions

View File

@ -69,13 +69,11 @@ $(OBJDIR)/%.o: $(TESTDIR)/%.c $(OBJDIR)/
$(CC) $(CFLAGS) -c "$<" -o "$@" $(CC) $(CFLAGS) -c "$<" -o "$@"
$(BINDIR)/%.dbg $(BINDIR)/%: $(OBJDIR)/%.o $(BINDIR)/ $(BINDIR)/%.dbg $(BINDIR)/%: $(OBJDIR)/%.o $(BINDIR)/
$(PYTHON3) ./smold.py --debugout $(SMOLFLAGS) $(LIBS) "$<" "$@.dbg" $(PYTHON3) ./smold.py --debugout "$@.dbg" $(SMOLFLAGS) --ldflags=-Wl,-Map=$(BINDIR)/$*.map $(LIBS) "$<" "$@"
$(PYTHON3) ./smold.py $(SMOLFLAGS) --ldflags=-Wl,-Map=$(BINDIR)/$*.map $(LIBS) "$<" "$@"
$(PYTHON3) ./smoltrunc.py "$@" "$(OBJDIR)/$(notdir $@)" && mv "$(OBJDIR)/$(notdir $@)" "$@" && chmod +x "$@" $(PYTHON3) ./smoltrunc.py "$@" "$(OBJDIR)/$(notdir $@)" && mv "$(OBJDIR)/$(notdir $@)" "$@" && chmod +x "$@"
$(BINDIR)/%-crt.dbg $(BINDIR)/%-crt: $(OBJDIR)/%.lto.o $(OBJDIR)/crt1.lto.o $(BINDIR)/ $(BINDIR)/%-crt.dbg $(BINDIR)/%-crt: $(OBJDIR)/%.lto.o $(OBJDIR)/crt1.lto.o $(BINDIR)/
$(PYTHON3) ./smold.py --debugout $(SMOLFLAGS) $(LIBS) "$<" $(OBJDIR)/crt1.lto.o "$@.dbg" $(PYTHON3) ./smold.py --debugout "$@.dbg" $(SMOLFLAGS) --ldflags=-Wl,-Map=$(BINDIR)/$*-crt.map $(LIBS) "$<" $(OBJDIR)/crt1.lto.o "$@"
$(PYTHON3) ./smold.py $(SMOLFLAGS) --ldflags=-Wl,-Map=$(BINDIR)/$*-crt.map $(LIBS) "$<" $(OBJDIR)/crt1.lto.o "$@"
$(PYTHON3) ./smoltrunc.py "$@" "$(OBJDIR)/$(notdir $@)" && mv "$(OBJDIR)/$(notdir $@)" "$@" && chmod +x "$@" $(PYTHON3) ./smoltrunc.py "$@" "$(OBJDIR)/$(notdir $@)" && mv "$(OBJDIR)/$(notdir $@)" "$@" && chmod +x "$@"
.PHONY: all clean .PHONY: all clean

View File

@ -2,8 +2,10 @@
ENTRY(_smol_start) ENTRY(_smol_start)
PHDRS { PHDRS {
rodttxt PT_LOAD FLAGS(5); /* r-x */ dyn PT_DYNAMIC FLAGS(0); /* --- */
rwdt PT_LOAD FLAGS(6); /* rw- */ interp PT_INTERP FLAGS(0); /* --- */
rodttxt PT_LOAD FLAGS(5); /* r-x */
rwdt PT_LOAD FLAGS(6); /* rw- */
} }
SECTIONS { SECTIONS {
@ -11,6 +13,8 @@ SECTIONS {
_smol_origin = .; _smol_origin = .;
.header : { KEEP(*(.header)) } :rodttxt .header : { KEEP(*(.header)) } :rodttxt
.dynamic : { *(.dynamic .rodata.dynamic) } :dyn :rodttxt
.interp : { *(.interp .rodata.interp) } :interp /*:rodttxt*/
_smol_text_start = .; _smol_text_start = .;
_smol_text_off = _smol_text_start - _smol_origin; _smol_text_off = _smol_text_start - _smol_origin;
@ -34,8 +38,7 @@ SECTIONS {
*(.data .data.* .tdata .tdata.*) *(.data .data.* .tdata .tdata.*)
} :rwdt } :rwdt
.dynamic : { *(.dynamic) } :rodttxt :dyn .dynstuff : { *(.symtab .strtab .shstrtab .rel.text .got.plt .gnu.linkonce.* .plt .plt.got) } /*:dyn*/ :rodttxt
.dynstuff : { *(.symtab .strtab .shstrtab .rel.text .got.plt .gnu.linkonce.* .plt .plt.got .interp) } :rodttxt
_smol_data_end = .; _smol_data_end = .;
_smol_data_size = _smol_data_end - _smol_data_start; _smol_data_size = _smol_data_end - _smol_data_start;

View File

@ -31,7 +31,7 @@ def nasm_assemble_elfhdr(verbose, nasm_bin, arch, rtdir, intbl, output, asflags)
def ld_link_final(verbose, cc_bin, arch, lddir, inobjs, output, ldflags, debug): def ld_link_final(verbose, cc_bin, arch, lddir, inobjs, output, ldflags, debug):
archflag = '-m64' if arch == "x86_64" else '-m32' archflag = '-m64' if arch == "x86_64" else '-m32'
args = [cc_bin, archflag, '-L', lddir, '-T', lddir+('/link_%s.ld'%arch), '-no-pie'] args = [cc_bin, archflag, '-L', lddir, '-T', '%s/link_%s.ld'%(lddir,arch), '-no-pie']
if not debug: if not debug:
args.append('-Wl,--oformat=binary') args.append('-Wl,--oformat=binary')
#args = [*args, '-T', lddir+'/link.ld', '-Wl,--oformat=binary'] #args = [*args, '-T', lddir+'/link.ld', '-Wl,--oformat=binary']

View File

@ -87,11 +87,11 @@ def main():
parser.add_argument('--readelf', default=os.getenv('READELF') or shutil.which('readelf'), \ parser.add_argument('--readelf', default=os.getenv('READELF') or shutil.which('readelf'), \
help="which readelf binary to use") help="which readelf binary to use")
parser.add_argument('--cflags', default=[], metavar='CFLAGS', action='append', parser.add_argument('-Wc','--cflags', default=[], metavar='CFLAGS', action='append',
help="Flags to pass to the C compiler for the relinking step") help="Flags to pass to the C compiler for the relinking step")
parser.add_argument('--asflags', default=[], metavar='ASFLAGS', action='append', parser.add_argument('-Wa','--asflags', default=[], metavar='ASFLAGS', action='append',
help="Flags to pass to the assembler when creating the ELF header and runtime startup code") help="Flags to pass to the assembler when creating the ELF header and runtime startup code")
parser.add_argument('--ldflags', default=[], metavar='LDFLAGS', action='append', parser.add_argument('-Wl','--ldflags', default=[], metavar='LDFLAGS', action='append',
help="Flags to pass to the linker for the final linking step") help="Flags to pass to the linker for the final linking step")
parser.add_argument('--smolrt', default=os.getcwd()+"/rt", parser.add_argument('--smolrt', default=os.getcwd()+"/rt",
help="Directory containing the smol runtime sources") help="Directory containing the smol runtime sources")
@ -102,10 +102,10 @@ def main():
help="Be verbose about what happens and which subcommands are invoked") help="Be verbose about what happens and which subcommands are invoked")
parser.add_argument('--keeptmp', default=False, action='store_true', \ parser.add_argument('--keeptmp', default=False, action='store_true', \
help="Keep temp files (only useful for debugging)") help="Keep temp files (only useful for debugging)")
parser.add_argument('--debugout', default=False, action='store_true', \ parser.add_argument('--debugout', type=str, default=None, \
help="Output an unrunnable debug ELF file with symbol information. "+\ help="Write out an additional, unrunnable debug ELF file with symbol "+\
"(Useful for debugging with gdb, cannot be ran due to broken "+\ "information. (Useful for debugging with gdb, cannot be ran due "+\
"relocations.)") "to broken relocations.)")
parser.add_argument('input', nargs='+', help="input object file") parser.add_argument('input', nargs='+', help="input object file")
parser.add_argument('output', type=str, help="output binary") parser.add_argument('output', type=str, help="output binary")
@ -130,13 +130,13 @@ def main():
for x in ['nasm','cc','scanelf','readelf']: for x in ['nasm','cc','scanelf','readelf']:
val = args.__dict__[x] val = args.__dict__[x]
if val is None or not os.path.isfile(val): if val is None or not os.path.isfile(val):
error("'" + x + "' binary" + (" " if val is None error("'%s' binary%s not found" %
else " ('" + val + "')") + " not found") (x, ("" if val is None else (" ('%s')" % val))))
arch = args.target.tolower() if len(args.target) != 0 else decide_arch(args.input) arch = args.target.tolower() if len(args.target) != 0 else decide_arch(args.input)
if arch not in archmagic: if arch not in archmagic:
error("Unknown/unsupported architecture '" + str(arch) + "'") error("Unknown/unsupported architecture '%s'" % str(arch))
if args.verbose: eprintf("arch: %s" % arch) if args.verbose: eprintf("arch: %s" % str(arch))
objinput = None objinput = None
objinputistemp = False objinputistemp = False
@ -160,7 +160,7 @@ def main():
spaths = args.libdir + cc_paths['libraries'] spaths = args.libdir + cc_paths['libraries']
libraries = cc_paths['libraries'] libraries = cc_paths['libraries']
libs = list(find_libs(spaths, args.library)) libs = list(find_libs(spaths, args.library))
if args.verbose: eprintf("libs = " + str(libs)) if args.verbose: eprintf("libs = %s" % str(libs))
symbols = {} symbols = {}
for symbol, reloc in syms: for symbol, reloc in syms:
library = find_symbol(args.scanelf, libs, args.library, symbol) library = find_symbol(args.scanelf, libs, args.library, symbol)
@ -180,7 +180,10 @@ def main():
# link with LD into the final executable, w/ special linker script # link with LD into the final executable, w/ special linker script
ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file], ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file],
args.output, args.ldflags, args.debugout) args.output, args.ldflags, False)
if args.debugout is not None:
ld_link_final(args.verbose, args.cc, arch, args.smolld, [objinput, tmp_elf_file],
args.debugout, args.ldflags, True)
finally: finally:
if not args.keeptmp: if not args.keeptmp:
if objinputistemp: os.remove(objinput) if objinputistemp: os.remove(objinput)