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

cmd/objdump: add -file-offset option #27941

Closed
mmcloughlin opened this issue Sep 29, 2018 · 7 comments
Closed

cmd/objdump: add -file-offset option #27941

mmcloughlin opened this issue Sep 29, 2018 · 7 comments
Labels
FeatureRequest FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@mmcloughlin
Copy link
Contributor

GNU binutils version of objdump offers a [-F|--file-offsets] flag

When disassembling sections, whenever a symbol is displayed, also display the file offset of the region of data that is about to be dumped. If zeroes are being skipped, then when disassembly resumes, tell the user how many zeroes were skipped and the file offset of the location from where the disassembly resumes. When dumping sections, display the file offset of the location from where the dump starts.

Example output on a Go binary:

...
000000000102e6c0 <runtime.schedule> (File Offset: 0x2e6c0):
 102e6c0:	65 48 8b 0c 25 30 00 	mov    %gs:0x30,%rcx
 102e6c7:	00 00
 102e6c9:	48 3b 61 10          	cmp    0x10(%rcx),%rsp
 102e6cd:	0f 86 3f 03 00 00    	jbe    102ea12 <runtime.schedule+0x352> (File Offset: 0x2ea12)
 102e6d3:	48 83 ec 40          	sub    $0x40,%rsp
 102e6d7:	48 89 6c 24 38       	mov    %rbp,0x38(%rsp)
 102e6dc:	48 8d 6c 24 38       	lea    0x38(%rsp),%rbp
...

This was useful for something I've been working on, and I think it would be fairly easy to add something like this to go tool objdump. Thoughts? If there's interest I could work on a CL.

@ALTree ALTree added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Sep 30, 2018
@ALTree
Copy link
Member

ALTree commented Sep 30, 2018

cc @randall77 for decision

@ALTree ALTree added this to the Go1.12 milestone Sep 30, 2018
@randall77
Copy link
Contributor

This was useful for something I've been working on

Could you describe how it would be useful?

Darwin objdump (Apple LLVM version 9.0.0 (clang-900.0.38)) does not have this option. My linux objdump does, but it didn't make the cut for the binary's one-page help page.

@mmcloughlin
Copy link
Contributor Author

I wanted to extract the text for a given symbol, or set of symbols.

Yes this is probably a niche use case, and there are other ways to do it (hence why its not made it into LLVM-based objdump). On the other hand its a fairly simple feature.

FWIW this gist shows a script to do it using the cmd/internal/objfile package https://gist.github.com/mmcloughlin/6167deb9591994183e96210d612c88a0 (objfile and other packages copied out of the internal namespace).

@randall77
Copy link
Contributor

It seems to me that you really want to be using a programmatic interface (like the gist) and not parsing objdump output. It seems a lot simpler than shelling out to objdump, parsing the output, then opening the file and reading the ranges you want.

objdump output is for humans. I don't want to add to it unless it's useful for humans. There are other interfaces that programs can use to access this information.

@mmcloughlin
Copy link
Contributor Author

There are other interfaces that programs can use to access this information.

I think the only problem with this is that the package you need to access objdump-like functionality is in an internal package.

Actually occurs to me that this feature may have been more useful in nm, for my use case at least. Then the script to do this is a simple combination of go tool nm and dd.

@randall77
Copy link
Contributor

This works on public interfaces only (but ELF only):

package main

import (
	"debug/elf"
	"fmt"
	"os"
)

func main() {
	file := os.Args[1]
	e, err := elf.Open(file)
	if err != nil {
		panic(err)
	}
	syms, err := e.Symbols()
	if err != nil {
		panic(err)
	}
	for _, s := range syms {
		if elf.ST_TYPE(s.Info) != elf.STT_FUNC {
			continue
		}
		sect := e.Sections[s.Section]
		fmt.Printf("%16x %16x %s\n", s.Value-sect.Addr+sect.Offset, s.Size, s.Name)
	}
}

It should be easy to grab the actual instruction bytes using the elf.Section.ReaderAt.

@mmcloughlin
Copy link
Contributor Author

Nice. Of course the benefit of the internal package is the abstraction layer over the object file format.

Feel free to close the ticket, it's not something I feel strongly about.

@golang golang locked and limited conversation to collaborators Oct 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FeatureRequest FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

4 participants