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 for DW_OP_addrx #242

Closed
wants to merge 4 commits into from
Closed

Support for DW_OP_addrx #242

wants to merge 4 commits into from

Conversation

gchamp20
Copy link

Hi,
I tried adding support for DW_OP_addrx. I am looking for feedback at this point since I'm not 100% everything I did is correct. Also, I am aware we would be missing a test for resume_with_addr_base.

I am not sure my interpretation of what DW_OP_addrx does is correct. I interpreted it as doing the same thing as DW_OP_addr, but in the .debug_addr section. In the case the I am correct, the implementation of DW_OP_constx would mostly reuse the same code I think?

@philipc
Copy link
Collaborator

philipc commented Aug 29, 2017

For DW_OP_addr the operand is a relative address, which means we simply add it to the .text base address, and the result is the address we want.

For DW_OP_addrx the operand is a relative section offset, which means that when we add it to the base section offset (defined by DW_AT_addr_base), the result is a section offset, not an address. To get the actual address, we need to read the value at that offset within the .debug_addr section. So the steps required are:

  • read the DW_OP_addrx operand
  • read DW_AT_addr_base attribute from the compilation unit DIE
  • read the address table header that is located at the addr_base offset within the .debug_addr section (see section 7.27 in the standard)
  • calculate the 'section offset' by adding the DW_OP_addrx operand to the DW_AT_addr_base value
  • read the address from that offset within the .debug_addr section, using the format that was specified in the address table header
  • I'm not sure if the address is also relative to .text

To implement this fully, we'll need support for parsing the .debug_addr section. I think this should be done externally to the struct Evaluation. So we'll need to define DebugAddr, DebugAddrOffset, and something for the table header, eg AddrTable. Once we have that, the resume API that we want will be something like:

fn resume_with_addr_table(&mut self, table: &AddrTable) -> Result<...>

As part of implementing this, we should also extend our dwarfdump example to print out these values too. It would be useful to find a compiler that generates DW_OP_addrx and .debug_addr for testing this.

@fitzgen
Copy link
Member

fitzgen commented Aug 29, 2017

Great write up @philipc.

Thanks for the PR and interest in providing this feature to gimli, @gchamp20! If you get stuck at all, feel free to ask questions or whatever here and myself and @philipc can help however we can. Good luck!

@gchamp20
Copy link
Author

Thanks a lot for the detailed answer @philipc.

I'll keep working on this.

@coveralls
Copy link

Coverage Status

Coverage decreased (-94.04%) to 0.0% when pulling 0b37504 on gchamp20:master into de7eeff on gimli-rs:master.

@gchamp20
Copy link
Author

gchamp20 commented Sep 18, 2017

Hi,

I'm having trouble finding a compiler that produces a debug_addr section that complies to the Address Table as specified in section 7.27.

g++ (version 6.3.1) and clang++ (version 3.9.1) will both produce a .debug_addr section if executed with -gsplit-dwarf. However, both compiler do not include the header specified by DWARF5. I suspect this is because -gsplit-dwarf was added for the DebugFission project and at that point the .debug_addr did not specify any header.

I tried looking for more info on that, but couldn't find anything. Can anyone confirm that clang nor gcc produces the correct format for the .debug_addr section?

If anyone is curious, here's the content of the .debug_addr section for a sample program that I compiled:

g++
Hex dump of section '.debug_addr':
0x00000000 a2074000 00000000 e0074000 00000000 ..@.......@.....
0x00000010 f6074000 00000000 66074000 00000000 ..@.....f.@.....
0x00000020 51116000 00000000 0b084000 00000000 Q.`.......@.....
0x00000030 b8084000 00000000 ..@.....

clang++
Hex dump of section '.debug_addr':
0x00000000 51116000 00000000 70064000 00000000 Q.`.....p.@.....
0x00000010 d0074000 00000000 20084000 00000000 ..@..... .@.....
0x00000020 c0064000 00000000 40084000 00000000 ..@.....@.@.....

@philipc
Copy link
Collaborator

philipc commented Sep 18, 2017

I didn't check gcc, but llvm doesn't write a header (source). So we probably need to handle .debug_addr differently based on whether it is referred to by DW_AT_addr_base or DW_AT_GNU_addr_base.

@tromey
Copy link
Member

tromey commented Sep 20, 2017

GCC also does not generate a header.

@philipc
Copy link
Collaborator

philipc commented Jan 14, 2019

Closing in favor of #358. Also FYI, parsing of the .debug_addr header was not needed because DW_AT_addr_base points past it, so sorry for misguiding you there.

@philipc philipc closed this Jan 14, 2019
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 this pull request may close these issues.

5 participants