b-s-a / binutils-gdb

Z80 development for binutils
GNU General Public License v2.0
6 stars 1 forks source link

Can not compile under Mac OS X #5

Open desertkun opened 3 years ago

desertkun commented 3 years ago

Hello. To finally add support for source level debugging for z88dk I've decided to come up with a tool that would convert *.map files into BFD files (efi or coff) which gdb would be able to load to show up debug information, the problem is I cannot compile this project on mac. This is really unfortunate because I am expecting to support the toolchain I am going to make, on Mac.

No matter how I've tried, getting some variants of this. Please save my soul I wasted a weekend on this to no avail.

libtool: link: gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -I./../zlib -g -O2 -Wl,-no_pie -o size size.o bucomm.o version.o filemode.o  ../bfd/.libs/libbfd.a -L/Users/desertkun/Documents/Work/binutils-gdb/zlib -ldl -lz ../libiberty/libiberty.a -L/usr/local/lib -lintl
ld: warning: ignoring file ../libiberty/libiberty.a, file was built for archive which is not the architecture being linked (x86_64): ../libiberty/libiberty.a
ld: warning: ignoring file ../bfd/.libs/libbfd.a, file was built for archive which is not the architecture being linked (x86_64): ../bfd/.libs/libbfd.a
Undefined symbols for architecture x86_64:
  "__bfd_std_section", referenced from:
      _sysv_internal_sizer in size.o
      _sysv_internal_printer in size.o
  "_bfd_arch_list", referenced from:
      _list_supported_architectures in bucomm.o
  "_bfd_check_format", referenced from:
      _display_file in size.o
      _display_bfd in size.o
  "_bfd_check_format_matches", referenced from:
      _display_bfd in size.o
  "_bfd_close", referenced from:
      _display_file in size.o
  "_bfd_close_all_done", referenced from:
      _do_display_target in bucomm.o
  "_bfd_core_file_failing_command", referenced from:
      _display_bfd in size.o
  "_bfd_errmsg", referenced from:
      _bfd_nonfatal in bucomm.o
      _bfd_nonfatal_message in bucomm.o
      _set_default_bfd_target in bucomm.o
  "_bfd_get_error", referenced from:
      _display_file in size.o
      _display_bfd in size.o
      _bfd_nonfatal in bucomm.o
      _bfd_nonfatal_message in bucomm.o
      _set_default_bfd_target in bucomm.o
      _do_display_target in bucomm.o
  "_bfd_init", referenced from:
      _main in size.o
  "_bfd_iterate_over_targets", referenced from:
      _display_info in bucomm.o
  "_bfd_map_over_sections", referenced from:
      _print_sizes in size.o
  "_bfd_openr", referenced from:
      _display_file in size.o
  "_bfd_openr_next_archived_file", referenced from:
      _display_file in size.o
  "_bfd_openw", referenced from:
      _do_display_target in bucomm.o
  "_bfd_printable_arch_mach", referenced from:
      _display_info in bucomm.o
      _do_display_target in bucomm.o
  "_bfd_scan_vma", referenced from:
      _parse_vma in bucomm.o
  "_bfd_set_default_target", referenced from:
      _set_default_bfd_target in bucomm.o
  "_bfd_set_error", referenced from:
      _display_file in size.o
  "_bfd_set_error_program_name", referenced from:
      _main in size.o
  "_bfd_set_format", referenced from:
      _do_display_target in bucomm.o
  "_bfd_target_list", referenced from:
      _list_supported_targets in bucomm.o
  "_expandargv", referenced from:
      _main in size.o
  "_make_temp_file", referenced from:
      _display_info in bucomm.o
  "_xexit", referenced from:
      _bfd_fatal in bucomm.o
      _fatal in bucomm.o
  "_xmalloc", referenced from:
      _print_sizes in size.o
      _bfd_get_archive_filename in bucomm.o
      _make_tempname in bucomm.o
      _make_tempdir in bucomm.o
  "_xmalloc_set_program_name", referenced from:
      _main in size.o
  "_xrealloc", referenced from:
      _do_display_target in bucomm.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[4]: *** [Makefile:938: size] Error 1
make[4]: Leaving directory '/Users/desertkun/Documents/Work/binutils-gdb/binutils'
make[3]: *** [Makefile:1135: all-recursive] Error 1
make[3]: Leaving directory '/Users/desertkun/Documents/Work/binutils-gdb/binutils'
make[2]: *** [Makefile:761: all] Error 2
make[2]: Leaving directory '/Users/desertkun/Documents/Work/binutils-gdb/binutils'
make[1]: *** [Makefile:3678: all-binutils] Error 2
make[1]: Leaving directory '/Users/desertkun/Documents/Work/binutils-gdb'

All I need is bfd.h and the library itself, to be able to produce z80-compatible BFD files.

I've tried:

ladmanj commented 3 years ago

That's great you will try to make the symbols import. Unfortunately I can't try it on Mac, because I have no access to one.

I have iMac6.1, along other garbage, with 32 bit x86, but i can't install resonably recent versions of software. Also the machne is very slow and unstable due to some gpu bug. I don't like it in the end.

desertkun commented 3 years ago

I was able to resolve the thing by completely ditching out brew's binutils and other stuff.

The libraries are not still not getting installed though, I had to manually copy them over by doing the following shenanigans:

cd bfd
./configure --enable-targets=all --host=x86_64-apple-darwin18.7.0 --prefix=/usr/local/z80
make
make install
cd ../libiberty
./configure --enable-targets=all --host=x86_64-apple-darwin18.7.0 --prefix=/usr/local/z80
make
# make install does not copy this over
sudo cp libiberty.a /usr/local/z80/lib
cd ../intl
./configure --enable-targets=all --host=x86_64-apple-darwin18.7.0 --prefix=/usr/local/z80 --with-libiconv-type=static
make
# make install does not copy this over
sudo cp libintl.a /usr/local/z80/lib

I am missing something? Do you have bandwidth to test if these are copied over on your machine?

kfazz commented 3 years ago

You may be using the wrong target spec. I use ../configure --target=z80-elf --enable-targets=all --prefix=$HOME/z180 successfully on linux. Note that with gcc 10 you will need to patch bfd/elf-bfd.h and change num_group from int to unsigned int

As an aside, i've been trying to port the sdcc stm8 dwarf support to z(1)80 maybe this would be of interest to you https://github.com/kfazz/sdcc/tree/z180_dwarf

desertkun commented 3 years ago

Thanks for the great tip. How can I integrate that into z88dk? Or I am not supposed to? I've installed it and specified -compiler sdcc -Cs="--dwarf --asm=gas" but it keeps using z88dk-asm, how do I make it switch over to z80-elf-as?

kfazz commented 3 years ago

i have added z80asm support now, if you recompile it might work. something like this should work: sdcc --out-fmt-elf --debug --no-peep --no-c-in-asm test.c

I haven't tested building anything with z88dk however. take a look at the readme to see how to compile a single file with either z80asm or binutils as backend. switching a project to use binutils isn't really trivial, you'll have to recompile all used libraries and write a linker script, and modify your makefile to invoke the proper tools with needed args, etc

desertkun commented 3 years ago

Thanks a lot for your effort. I don't have a project yet, so whichever works. So I wrote this rule:

%.o: %.c
    $(CC) $(CFLAGS) -S $< -o $@.asm
    $(AS) -sdcc $@.asm -o $@

It translates to following:

sdcc --codeseg .text --out-fmt-elf --asm=gas -S src/main.c -o src/main.o.asm
z80-elf-as -sdcc src/main.o.asm -o src/main.o

Couple of questions:

  1. How to I compile this with just a -c option, aka how to make sdcc to use z80-elf-as internally? It breaks if I would do so.
  2. How to I link the thing? z80-elf-ld src/main.o src/sum.o -o hello errors like so:
    z80-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000000100
    z80-elf-ld: src/main.o: in function `_main':
    main.c:(.text+0x24): undefined reference to `_printf'

    I imagine the crt0 is missing. But how do I link it?

Again thanks a lot.

desertkun commented 3 years ago

Never mind, I think I've resolved it. The complete script:

sdasz80 -g -l -s -o src/crt0.s.rel src/crt0.s
sdasz80 -g -l -s -o src/putchar.s.rel src/putchar.s
sdcc -mz80 --out-fmt-elf -c src/main.c -o src/main.rel
sdcc -mz80 --out-fmt-elf -c src/sum.c -o src/sum.rel
sdcc --out-fmt-elf -l z80 --no-std-crt0 --code-loc 0x8000 src/crt0.s.rel src/putchar.s.rel src/main.rel src/sum.rel -o hello.elf
z80-elf-objcopy -O binary hello.elf hello.bin
bintap -t 'Hello, Z80' -b --bc 7 --pc 7 --ic 0 -o hello.tap hello.bin

But the debugging info gets lost or what? z80-elf-gdb hello.elf just says:

Reading symbols from hello.elf...
(No debugging symbols found in hello.elf)

Same happens with main.elf produced by simple sdcc --out-fmt-elf src/main.c. I am SO close. How can I make gdb love elf?

kfazz commented 3 years ago

add the --debug flag to sdcc, this makes it emit the .debug* dwarf debugging sections into the generated asm. similarly you can also pass -g to gas to add debugging for assembly files that get linked as well. (but not both for the same file, or they will collide).

desertkun commented 3 years ago

Thanks a lot! With custom gdbserver on fuse and those settings I've been able to attach and even examine the stuff! However, I am also getting this.

Breakpoint 2, sum (a=-15040, b=-12843) at src/sum.c:3
3       return a + b;
(gdb) bt
#0  sum (a=-15040, b=-12843) at src/sum.c:3
#1  0x00008029 in main () at src/main.c:8
#2  0x00000f00 in ?? ()
#3  0x0000800c in ?? ()
#4  0x00001c85 in ?? ()
#5  0x00001c10 in ?? ()
#6  0x00001303 in ?? ()
#7  0x00003900 in ?? ()
#8  0x0000200a in ?? ()
#9  0x0000837e in ?? ()
#10 0x000021e5 in ?? ()
#11 0x00000004 in ?? ()
#12 0x00003900 in ?? ()
#13 0x000012cd in ?? ()
#14 0x00000004 in ?? ()
#15 0x000021e5 in ?? ()
#16 0x000021e5 in ?? ()
#17 0x00000004 in ?? ()
#18 0x000021e5 in ?? ()
#19 0x00000004 in ?? ()
#20 0x000021e5 in ?? ()
#21 0x00003900 in ?? ()
#22 0x00003900 in ?? ()
#23 0x0000045e in ?? ()
#24 0x000021d5 in ?? ()
#25 0x00003900 in ?? ()
#26 0x00000401 in ?? ()
.. goes on indefinitely

As I read about it on the docs, seems like something along the lines of set backtrace past-main not working. Is this some debugging info missing?

I am happy to share all my code pieces, however, I am working on fuse for Mac, so you won't be able to use my gdbserver, unless I port those changes to Linux version of fuse.

desertkun commented 3 years ago

I think I have figured out the reason, that's because the elf file does not contain the main symbol but rather has _main instead.

So the debugging_symbols section has info about main while the symbols themselves have only _main.

SYMBOL TABLE:
00008117 g     F *ABS*  00000000 _main
00000000 g     F *ABS*  00000000 .__.ABS.
00008100 g     F *ABS*  00000000 __clock
00008104 g     F *ABS*  00000000 _exit
0000814e g     F *ABS*  00000000 gsinit
00000000 g     F *ABS*  00000000 .__.ABS.
0000810a g     F *ABS*  00000000 _putchar
0000810a g     F *ABS*  00000000 _putchar_rr_s
00000000 g     F *ABS*  00000000 .__.ABS.
00008137 g     F *ABS*  00000000 _sum
00008135 g     F *ABS*  00000000 A$main$104
00008117 g     F *ABS*  00000000 _main
00008135 g     F *ABS*  00000000 Smain$main$10
00008135 g     F *ABS*  00000000 Smain$main$11
00008135 g     F *ABS*  00000000 Smain$main$12
00008137 g     F *ABS*  00000000 Smain$main$13
00008135 g     F *ABS*  00000000 XG$main$0$0
0000811b g     F *ABS*  00000000 A$main$60
0000811d g     F *ABS*  00000000 A$main$61
00008117 g     F *ABS*  00000000 Smain$main$0
0000812d g     F *ABS*  00000000 A$main$80
00008117 g     F *ABS*  00000000 Smain$main$1
0000812e g     F *ABS*  00000000 A$main$90
00008117 g     F *ABS*  00000000 Smain$main$2
00008131 g     F *ABS*  00000000 A$main$91
00008124 g     F *ABS*  00000000 A$main$73
0000811e g     F *ABS*  00000000 A$main$64
0000811e g     F *ABS*  00000000 Smain$main$3
00008132 g     F *ABS*  00000000 A$main$92
00008127 g     F *ABS*  00000000 A$main$74
00008121 g     F *ABS*  00000000 Smain$main$4
00008128 g     F *ABS*  00000000 A$main$75
00008124 g     F *ABS*  00000000 Smain$main$5
00008129 g     F *ABS*  00000000 A$main$76
00008121 g     F *ABS*  00000000 A$main$67
00008117 g     F *ABS*  00000000 A$main$58
0000812e g     F *ABS*  00000000 Smain$main$6
0000812a g     F *ABS*  00000000 A$main$77
00008122 g     F *ABS*  00000000 A$main$68
0000811a g     F *ABS*  00000000 A$main$59
0000812e g     F *ABS*  00000000 Smain$main$7
0000812b g     F *ABS*  00000000 A$main$78
00008123 g     F *ABS*  00000000 A$main$69
0000812e g     F *ABS*  00000000 Smain$main$8
0000812c g     F *ABS*  00000000 A$main$79
00008135 g     F *ABS*  00000000 Smain$main$9
00008020 g     F _GSFINAL       00000000 Fmain$test$0_0$0
00008022 g     F INITIALIZED    00000000 Fmain$__xinit_test$0_0$0
00000000 g     F *ABS*  00000000 .__.ABS.
...

Additionally, within the debugging symbols table, the main entity lacks DW_AT_main_subprogram flag.

 <1><39>: Abbrev Number: 3 (DW_TAG_subprogram)
    <3a>   DW_AT_sibling     : <0x6f>
    <3e>   DW_AT_name        : main
    <43>   DW_AT_low_pc      : 0x8117
    <47>   DW_AT_high_pc     : 0x8136
    <4b>   DW_AT_external    : 1
    <4c>   DW_AT_frame_base  : 0x0 (location list)
    <50>   DW_AT_type        : <0x32>
    <54>   DW_AT_main_subprogram: 1 <<<<<< missing

This entity tells gdb this debugging symbol is the main entry, which is used as a "stop" doing the backtrace.

frame.c:2306

  if (this_frame->level >= 0
      && get_frame_type (this_frame) == NORMAL_FRAME
      && !user_set_backtrace_options.backtrace_past_main
      && frame_pc_p
      && inside_main_func (this_frame)) <<<<< fails because there's no such symbol as "main".

I think the fix should be either generate symbols without _ in prefixes, or make debugging symbols start with one.

kfazz commented 3 years ago

the symbols being prepended with _ seems to be z80 specific behavior of sdcc, i'll take another look at it next weekend

ladmanj commented 3 years ago

Hi If it's possible to disable the _ beginning of the symbols, without any weird side effects, that will be absolutely great.

desertkun commented 3 years ago

@kfazz sorry for pushing it, did you have a chance to look at it?

desertkun commented 3 years ago

I think I have found how it's defined, it's an "_" set as part of z80_port for the fun_prefix member of the PORT structure. Once I've replaced it with "" the debugging started to behave correctly.

I also found this hack for isas assembler,

One exception being, is crt0 (including mine) still expects main symbol so when compiled we're faced with a liker error. So a proper fix could be to replace `""with"", remove that hack and fix up crt0 to link newmain`?

I have a proof of concept of successful gdb session using modified Fuse with gdbserver support, so I would like to ask for a bit of support with this getting resolved, so I can submit gdbserver support to Fuse having proper compiler people can test my PRRQ with.

ladmanj commented 3 years ago

Hi, that's really great.The question is whether there are any side effects.On the other hand the standard crt0.s can be easily disabled and replaced by a custom start up code.Of course also the standard crt0.s which is part of the library can be modified and recompiled.I have recompiled the whole library using the b-s-a's gnu-as year ago. It wasn't effortless, but doable.Now i haven't enough time playing with it unfortunately.J.Dne 29. 4. 2021 23:59 napsal uživatel Alex Siryi @.***>: I think I have found how it's defined, it's an "_" set as part of z80_port for the fun_prefix member of the PORT structure. Once I've replaced it with "" the debugging started to behave correctly. I also found this hack for isas assembler,

One exception being, is crt0 (including mine) still expects main symbol so when compiled we're faced with a liker error. So a proper fix could be to replace "" with "", remove that hack and fix up crt0 to link new main? I have a proof of concept of successful gdb session using modified Fuse with gdbserver support, so I would like to ask for a bit of support with this getting resolved, so I can submit gdbserver support to Fuse having proper compiler people can test my PRRQ with.

—You are receiving this because you commented.Reply to this email directly, view it on GitHub, or unsubscribe.

desertkun commented 3 years ago

Ugh, I've tried to investigate it more to see if there's a way to retain the _ symbols internally while reporting non-prefixed values to the elf file.

When a *.rel file is compiled with sdcc -mz80 --out-fmt-elf --debug -c src/sum.c -o src/sum.rel, elf information is embedded inside of .rel and .sym files. The trick is how to retain the fact there are _ rnames (internal names) and names (public names), because rnames are the ones used by the linker later on.

So far I've managed to extend things a little:

  dwAddTagAttr(dwFuncTag, dwNewAttrString(DW_AT_name, sym->name));
  dwAddTagAttr(dwFuncTag, dwNewAttrString(DW_AT_linkage_name, sym->rname)); // << added

The tricky one is this one:

dwAddTagAttr(dwFuncTag, dwNewAttrAddrSymbol(DW_AT_low_pc, sym, 0));

which does this internally

  ap->val.symaddr.label = sym->rname;
  ap->val.symaddr.offset = offset;

So each function tag has an address reference using rname. I tried to simply use just names here an got following linker errors:

?ASlink-Warning-Undefined Global 'test' referenced by module 'main'
?ASlink-Warning-Undefined Global 'sum' referenced by module 'sum'
?ASlink-Warning-Undefined Global 'main' referenced by module 'main'

I think those are assembled symbols the address is referring to, so the function above has to point to rname. So the trick of keeping _ prefixes and generating elf files without them is to properly retain name/rname information between compilation/link stage.

Could not find where those sym/rel files are parsed at linker stage in order to restore rnames properly from those files and not simply get the name (e.g. main instead of _main) . E.g. my command is:

sdcc --out-fmt-elf -l z80 --no-std-crt0 --code-loc 0x8100 --data-loc 0x8020 --stack-loc 0xffff --debug src/crt0.s.rel file1.rel file2.rel file3.rel -o hello.elf

Any tips?