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

gimli::write: support relocation in expression #474

Closed
wwylele opened this issue Mar 24, 2020 · 4 comments · Fixed by #479
Closed

gimli::write: support relocation in expression #474

wwylele opened this issue Mar 24, 2020 · 4 comments · Fixed by #479
Assignees

Comments

@wwylele
Copy link

wwylele commented Mar 24, 2020

I am generating DWARF on fly with the object file. I want to specify DW_AT_location for a global variable, which would be a constant address in the .data section and would require relocation (since I am also generating the .data section before linking and don't know the final address yet). Unlike other places that needs relocation and that supports gimli::write::Address::Symbol, DW_AT_location expects an expression and I can't find a sane way to add the relocation. Here is what I have tried:

  • Use DW_OP_addr followed by the address. The address needs relocation, but I would need to know where the "from" point to when writing the relocation entry, which gimli doesn't give.
  • Use DW_OP_addrx followed by an index into .debug_addr section, and do relocation there. However,
    • gimli::write doesn't support .debug_addr. Not a big deal as I can manually craft one, but
    • I need to set DW_AT_addr_base to the unit, which expects a section offset into .debug_addr (addrptr class) but gimli::write::AttributeValue doesn't support it.
    • This thing seems to be new in DWARF 5 and I wanted a lower version.

Any idea how I can do the relocation and/or can you implement the feature to support it?

@philipc
Copy link
Collaborator

philipc commented Mar 24, 2020

gimli definitely needs to implement better support for writing expressions. The current Expression is just a stopgap solution. I haven't implemented a better solution yet because it's not something I've used personally and so I don't know what the API should look like.

The simplest thing that supports relocations would be to use a Vec of an enum that represents DW_OP_* values. The variant for DW_OP_addr should contain an Address so the relocation can be generated when the expression is written. When .debug_addr support is implemented, the variant for DW_OP_addrx should contain an AddressId.

I'm not sure how DW_OP_bra and DW_OP_skip should be handled. Is it enough for them to specify an operation index, or do we need something like labels so that the producer doesn't need to compute the index themselves? Maybe a relative index is good enough?

I'm also not sure if the memory usage of this approach is too high. There can be many expressions and using an enum like this has some overhead. Maybe an expression should be Expression(Vec<u8>, Vec<ExpressionRelocation>) instead.

@bjorn3 and @yurydelendik might have thoughts about this.

@yurydelendik
Copy link
Contributor

It is hard to guess what's behind of Expression(Vec<u8>, Vec<ExpressionRelocation>) data structure. Ideally that shall be written into the Write and also use write_address(). When the Expression is constructed, chunks of bytes and (Address, u8)s will be interleaved.

Yes, Expression(Vec<u8>, Vec<ExpressionRelocation>) can be the data structure. The .0 is the expression data and reserves addresses data with 0-islands, and the ExpressionRelocation refers these island, and contains size and Address fields. Though serialization into Writer needs to be done in chunks and via write_address IMHO

@philipc
Copy link
Collaborator

philipc commented Mar 24, 2020

Yeah that's what I meant, sorry for being so brief. Although I was thinking we could have a write_address_at instead of needing to do chunks.

Also to expand a bit more, the API for adding operations could still use an enum for the operation, we'd just immediately convert it to bytes and automatically handle creating the 0-islands and the ExpressionRelocation.

@philipc
Copy link
Collaborator

philipc commented Apr 5, 2020

Using Expression(Vec<u8>, Vec<ExpressionRelocation>) isn't going to work because typed stack operations use uleb128 for base types, so they can't be generated until after base types are emitted. This also means that we need to change the .debug_info generation to output base types before DIEs with stack operations. gcc does something similar to this.

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.

3 participants