[RFC] Extend BBAddrMap Support to COFF/Windows

BBAddrMap provides metadata for basic block addresses and properties. It’s useful for post link optimization. The format of BBAddrMap is platform independent. We want to extend it to COFF so that Windows can also leverage it to apply post link optimization.

Current Limitations

The existing implementation has ELF-specific assumptions:

  • Type definitions in ELFTypes.h coupled to ELF
  • Encoding/decoding logic mixed with ELF-specific code in ELF.cpp
  • Section emission only for ELF targets
  • Tool support (llvm-readobj, llvm-objdump) only handles ELF

To extend it to COFF. We want to refactor some code.

Proposed Changes

1. Refactor for Multi-Format Support

  • Move BBAddrMap and PGOAnalysisMap types from ELFTypes.h to new shared header Object/BBAddrMap.h
  • Extract format-agnostic encoding/decoding to Object/BBAddrMap.cpp
  • Keep format-specific operations (decompression, relocations) in format-specific files

2. Enable COFF Support

Driver & MC Layer:

  • Remove ELF-only restriction in Clang driver
  • Support.llvm_bb_addr_map COFF sections

Object Library & Tools:

  • Implement COFFObjectFile::readBBAddrMap() for decoding
  • Handle COFF relocation types (IMAGE_REL_AMD64_ADDR64, IMAGE_REL_I386_DIR32, etc.)
  • Extend llvm-readobj and llvm-objdump for COFF BBAddrMap
  • Refactor common dumping logic into ObjDumper

I’d appreciate feedback from folks who worked on the original BBAddrMap
implementation @rlavaee @red1bluelost @boomanaiden154-1.

The overall approach LGTM. Glad to see that the infrastructure can be useful for Windows.

In ELF we map function sections to their SHT_LLVM_BB_ADDR_MAP section via sh_link attribute. Is there a similar feature in COFF?

Agreed this seems reasonable enough to me.

A bit off topic, but you mention you want to use this for PLO. Is the plan to get propeller to work on COFF/Windows, or to set up infrastructure for some other tooling?

Thanks for the feedback.

No. COFF does not have this feature. COFF identify BBAddrMap section (as well as other section like .llvm_addrsig) directly based on its section name.

Our current plan is set it up for some other tooling.

Patches to implement this:

  1. [NFC][Object] Move BBAddrMap related types to a shared header by HaohaiWen · Pull Request #187268 · llvm/llvm-project · GitHub
  1. [Object] Fix issues in BBAddrMap.h by HaohaiWen · Pull Request #187704 · llvm/llvm-project · GitHub
  1. [Object][NFC] Normalize BBAddrMap decode address types in ELF by HaohaiWen · Pull Request #187962 · llvm/llvm-project · GitHub
  1. [Object] Extract format-agnostic BBAddrMap decoder by HaohaiWen · Pull Request #188435 · llvm/llvm-project · GitHub
  1. [X86][COFF] Enable basic-block-address-map emission by HaohaiWen · Pull Request #191347 · llvm/llvm-project · GitHub

Also add yaml2obj/obj2yaml support.
6. [ObjectYAML][NFC] Extract BBAddrMap YAML types into shared namespace by HaohaiWen · Pull Request #196019 · llvm/llvm-project · GitHub