Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support go's Mach-O dwarf compression #696

Closed
ajwerner opened this issue Jun 18, 2024 · 3 comments · Fixed by #697
Closed

Support go's Mach-O dwarf compression #696

ajwerner opened this issue Jun 18, 2024 · 3 comments · Fixed by #697

Comments

@ajwerner
Copy link
Contributor

Go writes its dwarf sections with a somewhat bespoke format inspired by the GNU format with the ZLIB header. See: https://github.com/golang/go/blob/45446c867a3ffdf893bdfd1e1ef9e30166eaa157/src/debug/macho/file.go#L623-L645

One can manually work around this, but it'd be convenient for the implementation of ObjectSection for MachOSection to do it for users here:

#[inline]
fn compressed_file_range(&self) -> Result<CompressedFileRange> {
Ok(CompressedFileRange::none(self.file_range()))
}
#[inline]
fn compressed_data(&self) -> Result<CompressedData<'data>> {
self.data().map(CompressedData::none)
}

@philipc
Copy link
Contributor

philipc commented Jun 19, 2024

Does that mean none of the standard Mach-O system tools are able to parse these DWARF sections, only the go tools? e.g. does llvm support this at all?

I know little about go. Is it possible for me to create a Mach-O file containing these sections using a linux system?

@ajwerner
Copy link
Contributor Author

ajwerner commented Jun 19, 2024

Does that mean none of the standard Mach-O system tools are able to parse these DWARF sections, only the go tools? e.g. does llvm support this at all?

The llvm tools do not seem to work, no. Just the go tools seem to work.

I know little about go. Is it possible for me to create a Mach-O file containing these sections using a linux system?

Yes, you can. Go can natively cross compile. Consider:

package main

import "fmt"

func main() {
    fmt.Println("Hello world!")
}

GOOS=darwin go build -o main ./main.go

This will build a Mach-O file that can run on a mac from a linux machine.


There's actually two annoying things you'll notice about these binaries, and it's not the one I mention here that you'll likely hit first:

  1. They have different names for the debug sections: namely they don't have a . and they do have an __z (or sometimes apparently just __ prefix according to go code; I think the __z indicates compression).
llvm-objdump  --section-header main

main

Sections:
Idx Name             Size     VMA              Type
  0 __text           003ef5d0 0000000100001000 TEXT
  1 __symbol_stub1   00000540 00000001003f05e0 TEXT
  2 __rodata         000beff6 00000001003f0b20 DATA
  3 __rodata         0010d308 00000001004b0000 DATA
  4 __typelink       000036fc 00000001005bd320 DATA
  5 __itablink       00001340 00000001005c0a20 DATA
  6 __gosymtab       00000000 00000001005c1d60 DATA
  7 __gopclntab      0029d7a0 00000001005c1d60 DATA
  8 __go_buildinfo   000004b0 0000000100860000 DATA
  9 __nl_symbol_ptr  00000380 00000001008604b0 DATA
 10 __noptrdata      0003f9b8 0000000100860840 DATA
 11 __data           00012b90 00000001008a0200 DATA
 12 __bss            00038640 00000001008b2da0 BSS
 13 __noptrbss       00006a90 00000001008eb3e0 BSS
 14 __zdebug_abbrev  00000129 00000001008f4000 DATA, DEBUG
 15 __zdebug_line    0009a3b7 00000001008f4129 DATA, DEBUG
 16 __zdebug_frame   00028966 000000010098e4e0 DATA, DEBUG
 17 __debug_gdb_scri 00000018 00000001009b6e46 DATA, DEBUG
 18 __zdebug_info    0013525c 00000001009b6e5e DATA, DEBUG
 19 __zdebug_loc     000dd489 0000000100aec0ba DATA, DEBUG
 20 __zdebug_ranges  00030a61 0000000100bc9543 DATA, DEBUG
  1. The above compression thing.

I have code to deal with both, and the code described in this issue is really the more straightforward one. The first one applies more to the gimli crate than the object crate.

If you'd talk me through the testing you'd like to see, I'd be happy to send a patch for this.

@philipc
Copy link
Contributor

philipc commented Jun 19, 2024

We do already handle the '__'prefix. And we already handle a .z prefix for compressed ELF. So combining those two to support compressed Mach-O sections sounds reasonable.

For testing, ELF currently tests this by generating its own files. However, a better test is probably to add a file to https://github.com/gimli-rs/object-testfiles/tree/master/macho and then add something in tests/read/macho.rs that checks that Object::section_by_name and ObjectSection::compressed_data give the expected results. Also manually test that gimli's dwarfdump works as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants