Bug 19381 - Warn on instructions accessing small memory addresses, to catch un-tagged immediates
Summary: Warn on instructions accessing small memory addresses, to catch un-tagged imm...
Status: RESOLVED WONTFIX
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: unspecified
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-20 05:41 UTC by Josh Triplett
Modified: 2015-12-22 22:21 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Josh Triplett 2015-12-20 05:41:43 UTC
I recently spent a while debugging an issue caused by the following instruction:

subq 20, %rsp

That instruction accesses memory at absolute offset 20, rather than the intended immediate 20 ($20).

To catch cases like this, I would propose a new warning, on by default, that warns about instructions accessing a memory location less than 4096 (0x3ff).  (Or, on architectures with a different default page size, memory locations less than the default page size.)  In environments that trap null pointer accesses, such an access will normally trap.

Code that legitimately accesses such absolute addresses (such as code setting up a real-mode interrupt vector table) could easily turn this warning off.
Comment 1 Josh Triplett 2015-12-20 12:30:13 UTC
(In reply to Josh Triplett from comment #0)
> less than 4096 (0x3ff)

Half-edited sentence there; s/0x3ff/0x1000/, obviously.
Comment 2 Nick Clifton 2015-12-22 15:10:05 UTC
Hi Josh,

  You don't say which target you are using - some do have valid low memory addresses.

  Anyway it does not matter much as this is not really the job of the assembler or the linker.  A simulator or debugger is the appropriate place for a test such as this.

Cheers
  Nick
Comment 3 Josh Triplett 2015-12-22 22:21:54 UTC
(In reply to Nick Clifton from comment #2)
>   You don't say which target you are using - some do have valid low memory
> addresses.

The default warning threshold would need to be target-specific.  Many targets catch accesses to the lowest page of memory to trap NULL pointer dereferences.  If some target didn't have that, then sure, it couldn't have this cross-check.  Many common targets do, though.  And for those that don't have an obvious default target (e.g. if using an -elf target), the user could pass a warning option to set the threshold.

(In this case, x86_64-linux-gnu.)

>   Anyway it does not matter much as this is not really the job of the
> assembler or the linker.  A simulator or debugger is the appropriate place
> for a test such as this.

A hardware simulator was precisely how I ended up catching the problem, after hours of debugging and code inspection.  (And in the end, it wasn't the simulator itself that directly found the problem, but rather the fact that it disassembled using an assembler syntax that explicitly tags memory accesses.)  The assembler is what offers the easy-to-misuse syntax; I don't think it's unreasonable to have a "that's probably not what you meant" warning (just a warning, not an error).  This isn't a warning to attempt to catch NULL pointer dereferences in general; that *would* be a job for valgrind or similar.  This is a warning to catch memory references to tiny addresses written directly in the instruction, on the theory that absolute tiny addresses are vanishingly rare, and the user almost certainly meant to include the '$' for an immediate value instead.  The assembler already has numerous warnings for dubious assembly; for instance, attempting to assemble "addb $0x120, %al" will produce "Warning: 288 shortened to 32".