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

Add support for generating .map files #50

Open
bsirang opened this issue Jan 12, 2022 · 7 comments
Open

Add support for generating .map files #50

bsirang opened this issue Jan 12, 2022 · 7 comments

Comments

@bsirang
Copy link

bsirang commented Jan 12, 2022

I'm not too familiar with bazel toolchain specifications, so I'm not sure which component would be responsible for this, but I'd like to have .map files generated alongside the elf files when using bazel_embedded platforms. Is that something that's been looked at?

@nathaniel-brough
Copy link
Collaborator

This is something I'm also interested in, at the moment it looks like this will be a while off. There is an issue tracking this upstream.

bazelbuild/bazel#6718

I have a couple thoughts as to workarounds but it's unlikely I'll be able to do that in the near future.

@bsirang
Copy link
Author

bsirang commented Jan 14, 2022

@silvergasp can you share your thoughts on workarounds? Curious to understand the nature of them.

@nathaniel-brough
Copy link
Collaborator

So when you create a bazel rule e.g. cc_binary, you have to explicitly declare the inputs and outputs.

If you don't declare an output bazel effectively prevents you from using it either by sandboxing or simply deleting undeclared outputs.

This is kind of annoying but it is also why bazel is a lot better at being deterministic than other build systems.

There is a further snag on top of this in that the cc_* rules don't use the starlark plugin API, instead they are 'native' rules written in Java. So modifying the rules and the declared outputs to include .map files is somewhat involved, and requires upstream changes to bazel.

There is an ongoing effort to 'starlarkify' the cc_* rules. So this leads to the first approach I had in mind and that is to create a starlark version on cc_binary and potentially upstream that to rules_cc, or host that here under a different name. There are some examples of starlark rules in the bazelbuild/rules_cc repository that you could use as a starting point.

The second approach is to make use of the aspects API in bazel to extract the command line during linking, then effectively redo the linking with map file flags and just emitting the .map file as a declared output. This second approach is probably easier though has some real performance problems as you effectively end up linking twice.

There would likely be a lot of shared code between both approaches so you could likely go the aspects approach and then convert that to a dedicated rule later.

@nathaniel-brough
Copy link
Collaborator

Certainly happy to accept PRs if you have time to give it a go

@bsirang
Copy link
Author

bsirang commented Jan 19, 2022

Thanks for the brain dump @silvergasp !

@nathaniel-brough
Copy link
Collaborator

No worries. Some alternatives that I've found for map files, and are enough for my use cases (but don't fully replace map files).

  • google/bloaty
  • objdump (can run directly from bazel as these are exported_files)
  • readelf (can run directly from bazel as these are exported_files)

I've found bloaty particularly useful for tracking down where modules that are taking up a lot of space. I've also found the output of the above tools a lot easier to interpret, especially when automating things, as map files are a little bit hard to parse.

A nice way to maximise your mileage with these tools is to compile with debugging symbols e.g. -g3 but on your release builds, i.e. with -Os or -O2. This tells the linker to store all the DWARF info in your release build and contains all the source file paths, symbol names etc. from your build. You can then use the resulting ELF file with bloaty and then when you build the stripped version it will remove all the debug symbols. What is nice about this approach is that you end up with stripped binaries that are exactly identical to your release build while the ELF contains debug symbols. You can also use this approach to debug release builds, but it can be a little funky so YMMV. This isn't directly built into bazel-embedded but it's relatively simple to do e.g. add --copt=-g3 and --linkopt=-Wl,--gdb-index to your command line.

Out of interest, what specific info would you want to extract from your map files?

@bsirang
Copy link
Author

bsirang commented Feb 4, 2022

I didn't have a specific use case. I'm just used to having map files accessible to cross reference for debugging purposes. I'll try out the -g3 and --gdb-index flags.

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

No branches or pull requests

2 participants