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

llvm-nm yields incorrect result for Webassembly objects #33740

Closed
Madgen-content mannequin opened this issue Aug 31, 2017 · 3 comments
Closed

llvm-nm yields incorrect result for Webassembly objects #33740

Madgen-content mannequin opened this issue Aug 31, 2017 · 3 comments
Assignees
Labels
bugzilla Issues migrated from bugzilla tools:llvm-nm

Comments

@Madgen-content
Copy link
Mannequin

Madgen-content mannequin commented Aug 31, 2017

Bugzilla Link 34392
Resolution FIXED
Resolved on Sep 08, 2017 10:24
Version 5.0
OS Linux
Attachments test.c, armtest.o, wasmtest.o, wasmtestdis.wast
CC @dschuff,@sbc100

Extended Description

llvm-nm is able to process binary wasm object files and produce well-formatted results, but the results aren't sensible or useful. I'll outline the expected behaviour and actual behaviour.

If we have a file test.c with the contents
'''
char first[0xF];
char second[0xFF];
char third[0x9];
char fourth[0xA];
'''

and compile it to ARM using a clang that is set to target aarch64-unknown-linux-gnu with the command $CC -c test.c -o armtest.o we can look at the GNU nm output with nm -P armtest.o with the following results.
'''
$d.0 n 0000000000000000
first C 000000000000000f 000000000000000f
fourth C 000000000000000a 000000000000000a
second C 00000000000000ff 00000000000000ff
third C 0000000000000009 0000000000000009
'''

llvm-nm yields a similar enough result with llvm-nm -P armtest.o
'''
$d.0 n 0 0
first C f 0
fourth C a 0
second C ff 0
third C 9 0
'''

Now, we can compile test.c to wasm using a clang set to target wasm32-unknown-unknown-wasm with the command $CC -c test.c -o wasmtest.o. GNU nm, of course, just errors if you try to run it on wasmtest.o. However llvm-nm -P wasmtest.o yields the following.
'''
first D 0 0
fourth D 3 0
second D 1 0
third D 2 0
'''

It kinda just spits out the symbols with a number that indicates the relative declaration order.
It is worthwhile to take a look at the wasm-dis of wasmtest.o.
'''
(module
(global $global$0 i32 (i32.const 0))
(global $global$1 i32 (i32.const 16))
(global $global$2 i32 (i32.const 271))
(global $global$3 i32 (i32.const 280))
(table 0 anyfunc)
(memory $0 1)
(data (i32.const 0) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
(export "first" (global $global$0))
(export "second" (global $global$1))
(export "third" (global $global$2))
(export "fourth" (global $global$3))
;; custom section "linking", size 15
)
'''

Notice, lines 2-5 seem to indicate that the information necessary to determine symbol values/sizes and offsets is available in wasmtest.o, the file just isn't getting processed correctly. Somehow, for each symbol we're getting the 'x' out of it's '$global$x'.

test.c, armtest.o, wasmtest.o, and the wasm-dis are attached.

Sorry to preemptively ping you on this Derek. I couldn't file this under llvm-nm and something wasm related, so I figured I should at least tag someone on the wasm team to make you all aware.

GHC's build system actually relies on using nm at one point. Our current workaround is to compile with -flto and parse the llvm-dis of the necessary object files.

@Madgen-content
Copy link
Mannequin Author

Madgen-content mannequin commented Aug 31, 2017

assigned to @sbc100

@dschuff
Copy link
Member

dschuff commented Aug 31, 2017

@​Michael: Thanks for the report! No problem on pinging me. I've CC'd Sam Clegg, who is doing most of the work on wasm object files.

I think there are a couple of things going on here; First; I agree that the address/value of the symbol appears to be just getting printed as the index of its corresponding wasm global, and instead the initializer of that global should be printed (that's a pointer to the C global in the linear memory). This also seems to apply to llvm-objdump.

As for the size, that brings up another issue, which IIRC is that we currently don't support common symbols very well (or at all?). nm and objdump both handle those differently (objdump prints the alignment rather than the size of common symbols; I'm not sure what nm does; in your ARM example it looks like it's just printing the size as the value too). Anyway, I agree that we should print the size where applicable, and if not match one of the existing platforms, at least do something more useful than what we have now.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 8, 2017

Fixed in https://reviews.llvm.org/rL312294

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla tools:llvm-nm
Projects
None yet
Development

No branches or pull requests

2 participants