Browse Source

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

pull/17/head
PoroCYon 1 year ago
parent
commit
60d51bbc3b
4 changed files with 26 additions and 22 deletions
  1. +2
    -4
      Makefile
  2. +7
    -4
      ld/link_common.ld
  3. +1
    -1
      smol/cnl.py
  4. +16
    -13
      smold.py

+ 2
- 4
Makefile View File

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


+ 7
- 4
ld/link_common.ld View File

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


+ 1
- 1
smol/cnl.py 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):
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:
args.append('-Wl,--oformat=binary')
#args = [*args, '-T', lddir+'/link.ld', '-Wl,--oformat=binary']


+ 16
- 13
smold.py View File

@ -87,11 +87,11 @@ def main():
parser.add_argument('--readelf', default=os.getenv('READELF') or shutil.which('readelf'), \
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")
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")
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")
parser.add_argument('--smolrt', default=os.getcwd()+"/rt",
help="Directory containing the smol runtime sources")
@ -102,10 +102,10 @@ def main():
help="Be verbose about what happens and which subcommands are invoked")
parser.add_argument('--keeptmp', default=False, action='store_true', \
help="Keep temp files (only useful for debugging)")
parser.add_argument('--debugout', default=False, action='store_true', \
help="Output an unrunnable debug ELF file with symbol information. "+\
"(Useful for debugging with gdb, cannot be ran due to broken "+\
"relocations.)")
parser.add_argument('--debugout', type=str, default=None, \
help="Write out an additional, unrunnable debug ELF file with symbol "+\
"information. (Useful for debugging with gdb, cannot be ran due "+\
"to broken relocations.)")
parser.add_argument('input', nargs='+', help="input object file")
parser.add_argument('output', type=str, help="output binary")
@ -130,13 +130,13 @@ def main():
for x in ['nasm','cc','scanelf','readelf']:
val = args.__dict__[x]
if val is None or not os.path.isfile(val):
error("'" + x + "' binary" + (" " if val is None
else " ('" + val + "')") + " not found")
error("'%s' binary%s not found" %
(x, ("" if val is None else (" ('%s')" % val))))
arch = args.target.tolower() if len(args.target) != 0 else decide_arch(args.input)
if arch not in archmagic:
error("Unknown/unsupported architecture '" + str(arch) + "'")
if args.verbose: eprintf("arch: %s" % arch)
error("Unknown/unsupported architecture '%s'" % str(arch))
if args.verbose: eprintf("arch: %s" % str(arch))
objinput = None
objinputistemp = False
@ -160,7 +160,7 @@ def main():
spaths = args.libdir + cc_paths['libraries']
libraries = cc_paths['libraries']
libs = list(find_libs(spaths, args.library))
if args.verbose: eprintf("libs = " + str(libs))
if args.verbose: eprintf("libs = %s" % str(libs))
symbols = {}
for symbol, reloc in syms:
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
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:
if not args.keeptmp:
if objinputistemp: os.remove(objinput)


Loading…
Cancel
Save