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

Ghidra decompiler #2705

Closed
wants to merge 5 commits into from
Closed

Ghidra decompiler #2705

wants to merge 5 commits into from

Conversation

nimashoghi
Copy link

No description provided.

@mattgodbolt
Copy link
Member

Thanks for this! Will take a look in a while: sorry it's already been 5 days. (I'm on vacation for another week or so, but maybe someone else can take a look too)

Copy link
Member

@AbrilRBS AbrilRBS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the radio silence

export { LLVMMcaTool } from './llvm-mca-tool';
export { OSACATool } from './osaca-tool';
export { PaholeTool } from './pahole-tool';
export { PvsStudioTool } from './pvs-studio-tool';
export { ReadElfTool } from './readelf-tool';
export { StringsTool } from './strings-tool';
export { x86to6502Tool } from './x86to6502-tool';
export { x86to6502Tool } from './x86to6502-tool';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export { x86to6502Tool } from './x86to6502-tool';
export { x86to6502Tool } from './x86to6502-tool';

@@ -0,0 +1,167 @@
// Copyright (c) 2020, Compiler Explorer Authors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Copyright (c) 2020, Compiler Explorer Authors
// Copyright (c) 2021, Compiler Explorer Authors

// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// import {spawn} from "child_process"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// import {spawn} from "child_process"

Comment on lines 44 to 55
// const _demange = async (buffer) =>
// await new Promise((resolve, reject) => {
// const child = spawn("c++filt", ["--no-params"])
// child.on("error", (error) => reject(error))

// const bufs = []
// child.stdout.on("data", (chunk) => bufs.push(chunk))
// child.stdout.on("end", () => resolve(Buffer.concat(bufs)))

// child.stdin.write(buffer)
// child.stdin.end()
// })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// const _demange = async (buffer) =>
// await new Promise((resolve, reject) => {
// const child = spawn("c++filt", ["--no-params"])
// child.on("error", (error) => reject(error))
// const bufs = []
// child.stdout.on("data", (chunk) => bufs.push(chunk))
// child.stdout.on("end", () => resolve(Buffer.concat(bufs)))
// child.stdin.write(buffer)
// child.stdin.end()
// })

Comment on lines 142 to 163
// const startLineIndex = result.stdout.findIndex(
// (line) => line.text.trim() === START_INDICATOR,
// )
// const endLineIndex = result.stdout.findIndex(
// (line) => line.text.trim() === END_INDICATOR,
// )
// if (startLineIndex !== -1 && endLineIndex !== -1) {
// result.stdout = result.stdout.slice(
// startLineIndex + 1,
// endLineIndex,
// )
// }

// const exeDir = path.dirname(this.tool.exe)
// const output = await _demange(
// result.stdout.map((line) => line.text).join("\n"),
// )
// result.stdout = utils.parseOutput(
// output.toString("utf-8"),
// compilationInfo.executableFilename,
// exeDir,
// )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// const startLineIndex = result.stdout.findIndex(
// (line) => line.text.trim() === START_INDICATOR,
// )
// const endLineIndex = result.stdout.findIndex(
// (line) => line.text.trim() === END_INDICATOR,
// )
// if (startLineIndex !== -1 && endLineIndex !== -1) {
// result.stdout = result.stdout.slice(
// startLineIndex + 1,
// endLineIndex,
// )
// }
// const exeDir = path.dirname(this.tool.exe)
// const output = await _demange(
// result.stdout.map((line) => line.text).join("\n"),
// )
// result.stdout = utils.parseOutput(
// output.toString("utf-8"),
// compilationInfo.executableFilename,
// exeDir,
// )

@mattgodbolt
Copy link
Member

This looks like a great start, but as @RubenRBS has pointed out there's a few minor things to look at. From the amount of commented-out code it seems incomplete? Is this the case? Is there anything we need to know about to get this merged in, known limitations or similar?

@nimashoghi
Copy link
Author

First of all, thanks for the review @RubenRBS! I appreciate the comments.

@mattgodbolt, yes, you are correct that this implementation is incomplete and needs to be adjusted.

My primary limitation in implementing this is my lack of experience with the compiler explorer codebase, but with the implementation I have committed, the limitations are:

  1. Ghidra's decompiler must be installed beforehands.
  2. Ghidra's decompiler needs SLEIGH (instruction set description) files that need to be downloaded, and the SLEIGHHOME environment variable must point to this installation path.
  3. The decompiler tooling only works on binary outputs.
  4. Compiler explorer's built-in name demangling must be disabled. This means that Ghidra's output will also have demangled names.

My remaining tasks on this were:

  1. Figuring out how Compiler Explorer installs these different applications and making sure Ghidra's decompiler is installed properly. This would also involve making sure that Ghidra has the right SLEIGH (instruction set descriptions) installed for the instruction sets that it would be used on. This is due to limitations # 1 and # 2 above.
  2. (Less important) Using c++filt to demangle Ghidra's output symbols for functions. This is due to limitation # 4 described above. The commented code was for this demangler. I wanted to put behind some sort of a flag/setting, but I did not have the time to figure out how this is done with the Compiler Explorer's tooling API.

Finally, I have been a bit busy the past two weeks, but I will review these tasks, as well as @RubenRBS' comments and will push my changes accordingly. Please let me know if you have any comments or suggestions.

@mattgodbolt
Copy link
Member

Thanks @nimashoghi ! That's great. We can definitely help with 1. and 2. - there is a separate repo for installation and set up of apps etc. 3. is a bit of an issue but we have a number of tools that mandate "binary only", so it wouldn't be the first. 4. is something we can work on.

Thank you! We're here to help when you have time.

@github-actions github-actions bot added the ui label Jul 19, 2021
@nimashoghi
Copy link
Author

nimashoghi commented Jul 19, 2021

Ok, I have updated my code, which takes care of limitation #4.

I have also created a PR in the misc-builder repository which takes care of limitations #1 and #2.

Feel free to review everything and provide any feedback that you have.

I have also updated the tooling pane code to allow for word wrapping even if we're using the monaco editor as the output editor type. Previously, the word wrapping toggle button would be disabled in this case.

@mattgodbolt
Copy link
Member

Hi there! Sorry this went stale for so long. I'm trying to pick up the pieces here. The PR to misc-builder is still a draft: as far as I can tell this PR is blocked on that. I'll take a look there now.

@mattgodbolt
Copy link
Member

We seem to have stalled on this. I would like to get support but with https://dogbolt.org/ around I wonder if the need has reduced? I mean, taking source and compiling then decompiling is still valuable, which dogbolt doesn't do... so ... maybe still worth looking in to.

@mattgodbolt
Copy link
Member

Ok - I would love to have this but I'm going to close this. I'd be delighted to reopen. Ghidfra would be great, but this PR is a long way behind main these days, and we're moving more and more to typescript, which will make things worse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants