summaryrefslogtreecommitdiffstats
path: root/llvm/test/Instrumentation/HWAddressSanitizer
Commit message (Collapse)AuthorAgeFilesLines
* hwasan: add tag_offset DWARF attribute to optimized debug infoEvgenii Stepanov2019-12-121-0/+61
| | | | | | | | | | | | | | | Summary: Support alloca-referencing dbg.value in hwasan instrumentation. Update AsmPrinter to emit DW_AT_LLVM_tag_offset when location is in loclist format. Reviewers: pcc Subscribers: srhines, aprantl, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70753
* [hwasan] Remove lazy thread-initialisationDavid Spickett2019-11-041-39/+0
| | | | | | | | | | | | | | | | | | | | | This was an experiment made possible by a non-standard feature of the Android dynamic loader. It required introducing a flag to tell the compiler which ABI was being targeted. This flag is no longer needed, since the generated code now works for both ABI's. We leave that flag untouched for backwards compatibility. This also means that if we need to distinguish between targeted ABI's again we can do that without disturbing any existing workflows. We leave a comment in the source code and mention in the help text to explain this for any confused person reading the code in the future. Patch by Matthew Malcomson Differential Revision: https://reviews.llvm.org/D69574
* hwasan: Compatibility fixes for short granules.Peter Collingbourne2019-09-274-22/+52
| | | | | | | | | | | | | | | | | | | | | | | | | We can't use short granules with stack instrumentation when targeting older API levels because the rest of the system won't understand the short granule tags stored in shadow memory. Moreover, we need to be able to let old binaries (which won't understand short granule tags) run on a new system that supports short granule tags. Such binaries will call the __hwasan_tag_mismatch function when their outlined checks fail. We can compensate for the binary's lack of support for short granules by implementing the short granule part of the check in the __hwasan_tag_mismatch function. Unfortunately we can't do anything about inline checks, but I don't believe that we can generate these by default on aarch64, nor did we do so when the ABI was fixed. A new function, __hwasan_tag_mismatch_v2, is introduced that lets code targeting the new runtime avoid redoing the short granule check. Because tag mismatches are rare this isn't important from a performance perspective; the main benefit is that it introduces a symbol dependency that prevents binaries targeting the new runtime from running on older (i.e. incompatible) runtimes. Differential Revision: https://reviews.llvm.org/D68059 llvm-svn: 373035
* hwasan: Untag unwound stack frames by wrapping personality functions.Peter Collingbourne2019-08-232-4/+96
| | | | | | | | | | | | | | | | | | | | | | | One problem with untagging memory in landing pads is that it only works correctly if the function that catches the exception is instrumented. If the function is uninstrumented, we have no opportunity to untag the memory. To address this, replace landing pad instrumentation with personality function wrapping. Each function with an instrumented stack has its personality function replaced with a wrapper provided by the runtime. Functions that did not have a personality function to begin with also get wrappers if they may be unwound past. As the unwinder calls personality functions during stack unwinding, the original personality function is called and the function's stack frame is untagged by the wrapper if the personality function instructs the unwinder to keep unwinding. If unwinding stops at a landing pad, the function is still responsible for untagging its stack frame if it resumes unwinding. The old landing pad mechanism is preserved for compatibility with old runtimes. Differential Revision: https://reviews.llvm.org/D66377 llvm-svn: 369721
* hwasan: Instrument globals.Peter Collingbourne2019-08-061-0/+37
| | | | | | | | | | | | | | | | | | Globals are instrumented by adding a pointer tag to their symbol values and emitting metadata into a special section that allows the runtime to tag their memory when the library is loaded. Due to order of initialization issues explained in more detail in the comments, shadow initialization cannot happen during regular global initialization. Instead, the location of the global section is marked using an ELF note, and we require libc support for calling a function provided by the HWASAN runtime when libraries are loaded and unloaded. Based on ideas discussed with @evgeny777 in D56672. Differential Revision: https://reviews.llvm.org/D65770 llvm-svn: 368102
* Added address-space mangling for stack related intrinsicsChristudasan Devadasan2019-07-222-2/+2
| | | | | | | | | | | | Modified the following 3 intrinsics: int_addressofreturnaddress, int_frameaddress & int_sponentry. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D64561 llvm-svn: 366679
* hwasan: Initialize the pass only once.Peter Collingbourne2019-07-171-4/+4
| | | | | | | | | | This will let us instrument globals during initialization. This required making the new PM pass a module pass, which should still provide access to analyses via the ModuleAnalysisManager. Differential Revision: https://reviews.llvm.org/D64843 llvm-svn: 366379
* hwasan: Pad arrays with non-1 size correctly.Peter Collingbourne2019-07-164-9/+24
| | | | | | | | Spotted by eugenis. Differential Revision: https://reviews.llvm.org/D64783 llvm-svn: 366171
* hwasan: Improve precision of checks using short granule tags.Peter Collingbourne2019-07-094-10/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A short granule is a granule of size between 1 and `TG-1` bytes. The size of a short granule is stored at the location in shadow memory where the granule's tag is normally stored, while the granule's actual tag is stored in the last byte of the granule. This means that in order to verify that a pointer tag matches a memory tag, HWASAN must check for two possibilities: * the pointer tag is equal to the memory tag in shadow memory, or * the shadow memory tag is actually a short granule size, the value being loaded is in bounds of the granule and the pointer tag is equal to the last byte of the granule. Pointer tags between 1 to `TG-1` are possible and are as likely as any other tag. This means that these tags in memory have two interpretations: the full tag interpretation (where the pointer tag is between 1 and `TG-1` and the last byte of the granule is ordinary data) and the short tag interpretation (where the pointer tag is stored in the granule). When HWASAN detects an error near a memory tag between 1 and `TG-1`, it will show both the memory tag and the last byte of the granule. Currently, it is up to the user to disambiguate the two possibilities. Because this functionality obsoletes the right aligned heap feature of the HWASAN memory allocator (and because we can no longer easily test it), the feature is removed. Also update the documentation to cover both short granule tags and outlined checks. Differential Revision: https://reviews.llvm.org/D63908 llvm-svn: 365551
* hwasan: Remove the old frame descriptor mechanism.Peter Collingbourne2019-06-283-30/+0
| | | | | | Differential Revision: https://reviews.llvm.org/D63470 llvm-svn: 364665
* hwasan: Use llvm.read_register intrinsic to read the PC on aarch64 instead ↵Peter Collingbourne2019-06-271-0/+3
| | | | | | | | | | | of taking the function's address. This shaves an instruction (and a GOT entry in PIC code) off prologues of functions with stack variables. Differential Revision: https://reviews.llvm.org/D63472 llvm-svn: 364608
* hwasan: Use bits [3..11) of the ring buffer entry address as the base stack tag.Peter Collingbourne2019-06-172-6/+9
| | | | | | | | | | | | | | This saves roughly 32 bytes of instructions per function with stack objects and causes us to preserve enough information that we can recover the original tags of all stack variables. Now that stack tags are deterministic, we no longer need to pass -hwasan-generate-tags-with-calls during check-hwasan. This also means that the new stack tag generation mechanism is exercised by check-hwasan. Differential Revision: https://reviews.llvm.org/D63360 llvm-svn: 363636
* hwasan: Add a tag_offset DWARF attribute to instrumented stack variables.Peter Collingbourne2019-06-171-0/+50
| | | | | | | | | | | | | | | | | | | | | | | The goal is to improve hwasan's error reporting for stack use-after-return by recording enough information to allow the specific variable that was accessed to be identified based on the pointer's tag. Currently we record the PC and lower bits of SP for each stack frame we create (which will eventually be enough to derive the base tag used by the stack frame) but that's not enough to determine the specific tag for each variable, which is the stack frame's base tag XOR a value (the "tag offset") that is unique for each variable in a function. In IR, the tag offset is most naturally represented as part of a location expression on the llvm.dbg.declare instruction. However, the presence of the tag offset in the variable's actual location expression is likely to confuse debuggers which won't know about tag offsets, and moreover the tag offset is not required for a debugger to determine the location of the variable on the stack, so at the DWARF level it is represented as an attribute so that it will be ignored by debuggers that don't know about it. Differential Revision: https://reviews.llvm.org/D63119 llvm-svn: 363635
* HWASan exception support.Evgeniy Stepanov2019-05-161-0/+37
| | | | | | | | | | | | | | | | | | Summary: Adds a call to __hwasan_handle_vfork(SP) at each landingpad entry. Reusing __hwasan_handle_vfork instead of introducing a new runtime call in order to be ABI-compatible with old runtime library. Reviewers: pcc Subscribers: kubamracek, hiraditya, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D61968 llvm-svn: 360959
* [NewPM] Port HWASan and Kernel HWASanLeonard Chan2019-05-141-0/+6
| | | | | | | | | | | | | | | Port hardware assisted address sanitizer to new PM following the same guidelines as msan and tsan. Changes: - Separate HWAddressSanitizer into a pass class and a sanitizer class. - Create new PM wrapper pass for the sanitizer class. - Use the getOrINsert pattern for some module level initialization declarations. - Also enable kernel-kwasan in new PM - Update llvm tests and add clang test. Differential Revision: https://reviews.llvm.org/D61709 llvm-svn: 360707
* hwasan: Enable -hwasan-allow-ifunc by default.Peter Collingbourne2019-04-092-6/+6
| | | | | | | | | It's been on in Android for a while without causing problems, so it's time to make it the default and remove the flag. Differential Revision: https://reviews.llvm.org/D60355 llvm-svn: 357960
* hwasan: If we split the entry block, move static allocas back into the entry ↵Peter Collingbourne2019-01-251-2/+5
| | | | | | | | | | | | block. Otherwise they are treated as dynamic allocas, which ends up increasing code size significantly. This reduces size of Chromium base_unittests by 2MB (6.7%). Differential Revision: https://reviews.llvm.org/D57205 llvm-svn: 352152
* hwasan: Read shadow address from ifunc if we don't need a frame record.Peter Collingbourne2019-01-232-23/+27
| | | | | | | | | | | | | This saves a cbz+cold call in the interceptor ABI, as well as a realign in both ABIs, trading off a dcache entry against some branch predictor entries and some code size. Unfortunately the functionality is hidden behind a flag because ifunc is known to be broken on static binaries on Android. Differential Revision: https://reviews.llvm.org/D57084 llvm-svn: 351989
* hwasan: Move memory access checks into small outlined functions on aarch64.Peter Collingbourne2019-01-235-170/+171
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Each hwasan check requires emitting a small piece of code like this: https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#memory-accesses The problem with this is that these code blocks typically bloat code size significantly. An obvious solution is to outline these blocks of code. In fact, this has already been implemented under the -hwasan-instrument-with-calls flag. However, as currently implemented this has a number of problems: - The functions use the same calling convention as regular C functions. This means that the backend must spill all temporary registers as required by the platform's C calling convention, even though the check only needs two registers on the hot path. - The functions take the address to be checked in a fixed register, which increases register pressure. Both of these factors can diminish the code size effect and increase the performance hit of -hwasan-instrument-with-calls. The solution that this patch implements is to involve the aarch64 backend in outlining the checks. An intrinsic and pseudo-instruction are created to represent a hwasan check. The pseudo-instruction is register allocated like any other instruction, and we allow the register allocator to select almost any register for the address to check. A particular combination of (register selection, type of check) triggers the creation in the backend of a function to handle the check for specifically that pair. The resulting functions are deduplicated by the linker. The pseudo-instruction (really the function) is specified to preserve all registers except for the registers that the AAPCS specifies may be clobbered by a call. To measure the code size and performance effect of this change, I took a number of measurements using Chromium for Android on aarch64, comparing a browser with inlined checks (the baseline) against a browser with outlined checks. Code size: Size of .text decreases from 243897420 to 171619972 bytes, or a 30% decrease. Performance: Using Chromium's blink_perf.layout microbenchmarks I measured a median performance regression of 6.24%. The fact that a perf/size tradeoff is evident here suggests that we might want to make the new behaviour conditional on -Os/-Oz. But for now I've enabled it unconditionally, my reasoning being that hwasan users typically expect a relatively large perf hit, and ~6% isn't really adding much. We may want to revisit this decision in the future, though. I also tried experimenting with varying the number of registers selectable by the hwasan check pseudo-instruction (which would result in fewer variants being created), on the hypothesis that creating fewer variants of the function would expose another perf/size tradeoff by reducing icache pressure from the check functions at the cost of register pressure. Although I did observe a code size increase with fewer registers, I did not observe a strong correlation between the number of registers and the performance of the resulting browser on the microbenchmarks, so I conclude that we might as well use ~all registers to get the maximum code size improvement. My results are below: Regs | .text size | Perf hit -----+------------+--------- ~all | 171619972 | 6.24% 16 | 171765192 | 7.03% 8 | 172917788 | 5.82% 4 | 177054016 | 6.89% Differential Revision: https://reviews.llvm.org/D56954 llvm-svn: 351920
* Revert "Revert "[hwasan] Android: Switch from TLS_SLOT_TSAN(8) to ↵Evgeniy Stepanov2019-01-051-2/+2
| | | | | | | | TLS_SLOT_SANITIZER(6)"" This reapplies commit r348983. llvm-svn: 350448
* hwasan: Implement lazy thread initialization for the interceptor ABI.Peter Collingbourne2019-01-041-0/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The problem is similar to D55986 but for threads: a process with the interceptor hwasan library loaded might have some threads started by instrumented libraries and some by uninstrumented libraries, and we need to be able to run instrumented code on the latter. The solution is to perform per-thread initialization lazily. If a function needs to access shadow memory or add itself to the per-thread ring buffer its prologue checks to see whether the value in the sanitizer TLS slot is null, and if so it calls __hwasan_thread_enter and reloads from the TLS slot. The runtime does the same thing if it needs to access this data structure. This change means that the code generator needs to know whether we are targeting the interceptor runtime, since we don't want to pay the cost of lazy initialization when targeting a platform with native hwasan support. A flag -fsanitize-hwaddress-abi={interceptor,platform} has been introduced for selecting the runtime ABI to target. The default ABI is set to interceptor since it's assumed that it will be more common that users will be compiling application code than platform code. Because we can no longer assume that the TLS slot is initialized, the pthread_create interceptor is no longer necessary, so it has been removed. Ideally, lazy initialization should only cost one instruction in the hot path, but at present the call may cause us to spill arguments to the stack, which means more instructions in the hot path (or theoretically in the cold path if the spills are moved with shrink wrapping). With an appropriately chosen calling convention for the per-thread initialization function (TODO) the hot path should always need just one instruction and the cold path should need two instructions with no spilling required. Differential Revision: https://reviews.llvm.org/D56038 llvm-svn: 350429
* [HWASAN] Instrument memorty intrinsics by defaultEugene Leviant2018-12-241-1/+1
| | | | | | Differential revision: https://reviews.llvm.org/D55926 llvm-svn: 350055
* [HWASAN] Add support for memory intrinsicsEugene Leviant2018-12-201-0/+40
| | | | | | Differential revision: https://reviews.llvm.org/D55117 llvm-svn: 349728
* hwasan: Move ctor into a comdat.Peter Collingbourne2018-12-172-2/+5
| | | | | | Differential Revision: https://reviews.llvm.org/D55733 llvm-svn: 349413
* Revert "[hwasan] Android: Switch from TLS_SLOT_TSAN(8) to TLS_SLOT_SANITIZER(6)"Evgeniy Stepanov2018-12-131-2/+2
| | | | | | | | Breaks sanitizer-android buildbot. This reverts commit af8443a984c3b491c9ca2996b8d126ea31e5ecbe. llvm-svn: 349092
* [hwasan] Android: Switch from TLS_SLOT_TSAN(8) to TLS_SLOT_SANITIZER(6)Ryan Prichard2018-12-121-2/+2
| | | | | | | | | | | | | | | | Summary: The change is needed to support ELF TLS in Android. See D55581 for the same change in compiler-rt. Reviewers: srhines, eugenis Reviewed By: eugenis Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D55592 llvm-svn: 348983
* [hwasan] add stack frame descriptions.Kostya Serebryany2018-10-233-0/+29
| | | | | | | | | | | | | | | | | | | Summary: At compile-time, create an array of {PC,HumanReadableStackFrameDescription} for every function that has an instrumented frame, and pass this array to the run-time at the module-init time. Similar to how we handle pc-table in SanitizerCoverage. The run-time is dummy, will add the actual logic in later commits. Reviewers: morehouse, eugenis Reviewed By: eugenis Subscribers: srhines, llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D53227 llvm-svn: 344985
* [hwasan] Record and display stack history in stack-based reports.Evgeniy Stepanov2018-09-244-35/+92
| | | | | | | | | | | | | | | | | | | | | Summary: Display a list of recent stack frames (not a stack trace!) when tag-mismatch is detected on a stack address. The implementation uses alignment tricks to get both the address of the history buffer, and the base address of the shadow with a single 8-byte load. See the comment in hwasan_thread_list.h for more details. Developed in collaboration with Kostya Serebryany. Reviewers: kcc Subscribers: srhines, kubamracek, mgorny, hiraditya, jfb, llvm-commits Differential Revision: https://reviews.llvm.org/D52249 llvm-svn: 342923
* Revert "[hwasan] Record and display stack history in stack-based reports."Evgeniy Stepanov2018-09-244-92/+35
| | | | | | This reverts commit r342921: test failures on clang-cmake-arm* bots. llvm-svn: 342922
* [hwasan] Record and display stack history in stack-based reports.Evgeniy Stepanov2018-09-244-35/+92
| | | | | | | | | | | | | | | | | | | | | Summary: Display a list of recent stack frames (not a stack trace!) when tag-mismatch is detected on a stack address. The implementation uses alignment tricks to get both the address of the history buffer, and the base address of the shadow with a single 8-byte load. See the comment in hwasan_thread_list.h for more details. Developed in collaboration with Kostya Serebryany. Reviewers: kcc Subscribers: srhines, kubamracek, mgorny, hiraditya, jfb, llvm-commits Differential Revision: https://reviews.llvm.org/D52249 llvm-svn: 342921
* [hwasan] Add -hwasan-with-ifunc flag.Evgeniy Stepanov2018-08-101-0/+30
| | | | | | | | | | | | Summary: Similar to asan's flag, it can be used to disable the use of ifunc to access hwasan shadow address. Reviewers: vitalybuka, kcc Subscribers: srhines, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D50544 llvm-svn: 339447
* [HWASan] Do not retag allocas before return from the function.Alex Shlyapnikov2018-06-292-14/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Retagging allocas before returning from the function might help detecting use after return bugs, but it does not work at all in real life, when instrumented and non-instrumented code is intermixed. Consider the following code: F_non_instrumented() { T x; F1_instrumented(&x); ... } { F_instrumented(); F_non_instrumented(); } - F_instrumented call leaves the stack below the current sp tagged randomly for UAR detection - F_non_instrumented allocates its own vars on that tagged stack, not generating any tags, that is the address of x has tag 0, but the shadow memory still contains tags left behind by F_instrumented on the previous step - F1_instrumented verifies &x before using it and traps on tag mismatch, 0 vs whatever tag was set by F_instrumented Reviewers: eugenis Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D48664 llvm-svn: 336011
* [HWASan] Introduce non-zero based and dynamic shadow memory (LLVM).Alex Shlyapnikov2018-04-202-15/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Support the dynamic shadow memory offset (the default case for user space now) and static non-zero shadow memory offset (-hwasan-mapping-offset option). Keeping the the latter case around for functionality and performance comparison tests (and mostly for -hwasan-mapping-offset=0 case). The implementation is stripped down ASan one, picking only the relevant parts in the following assumptions: shadow scale is fixed, the shadow memory is dynamic, it is accessed via ifunc global, shadow memory address rematerialization is suppressed. Keep zero-based shadow memory for kernel (-hwasan-kernel option) and calls instreumented case (-hwasan-instrument-with-calls option), which essentially means that the generated code is not changed in these cases. Reviewers: eugenis Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D45840 llvm-svn: 330475
* hwasan: add -fsanitize=kernel-hwaddress flagAndrey Konovalov2018-04-132-7/+7
| | | | | | | | | This patch adds -fsanitize=kernel-hwaddress flag, that essentially enables -hwasan-kernel=1 -hwasan-recover=1 -hwasan-match-all-tag=0xff. Differential Revision: https://reviews.llvm.org/D45046 llvm-svn: 330044
* hwasan: add -hwasan-match-all-tag flagEvgeniy Stepanov2018-04-041-5/+11
| | | | | | | | | | | | | | | | Sometimes instead of storing addresses as is, the kernel stores the address of a page and an offset within that page, and then computes the actual address when it needs to make an access. Because of this the pointer tag gets lost (gets set to 0xff). The solution is to ignore all accesses tagged with 0xff. This patch adds a -hwasan-match-all-tag flag to hwasan, which allows to ignore accesses through pointers with a particular pointer tag value for validity. Patch by Andrey Konovalov. Differential Revision: https://reviews.llvm.org/D44827 llvm-svn: 329228
* [HWASan] Port HWASan to Linux x86-64 (LLVM)Alex Shlyapnikov2018-03-234-0/+256
| | | | | | | | | | | | | | | | | | | | | Summary: Porting HWASan to Linux x86-64, first of the three patches, LLVM part. The approach is similar to ARM case, trap signal is used to communicate memory tag check failure. int3 instruction is used to generate a signal, access parameters are stored in nop [eax + offset] instruction immediately following the int3 one. One notable difference is that x86-64 has to untag the pointer before use due to the lack of feature comparable to ARM's TBI (Top Byte Ignore). Reviewers: eugenis Subscribers: kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D44699 llvm-svn: 328342
* [hwasan] Fix inline instrumentation.Evgeniy Stepanov2018-02-214-35/+50
| | | | | | | | | | | | | | | This patch changes hwasan inline instrumentation: Fixes address untagging for shadow address calculation (use 0xFF instead of 0x00 for the top byte). Emits brk instruction instead of hlt for the kernel and user space. Use 0x900 instead of 0x100 for brk immediate (0x100 - 0x800 are unavailable in the kernel). Fixes and adds appropriate tests. Patch by Andrey Konovalov. Differential Revision: https://reviews.llvm.org/D43135 llvm-svn: 325711
* asan: add kernel inline instrumentation test (retry)Vedant Kumar2018-02-211-0/+28
| | | | | | | | | | Add a test that checks that kernel inline instrumentation works. Patch by Andrey Konovalov! Differential Revision: https://reviews.llvm.org/D42473 llvm-svn: 325710
* [hwasan] Fix kernel instrumentation of stack.Evgeniy Stepanov2018-02-091-0/+29
| | | | | | | | | | | | | | | Summary: Kernel addresses have 0xFF in the most significant byte. A tag can not be pushed there with OR (tag << 56); use AND ((tag << 56) | 0x00FF..FF) instead. Reviewers: kcc, andreyknvl Subscribers: srhines, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D42941 llvm-svn: 324691
* Remove alignment argument from memcpy/memmove/memset in favour of alignment ↵Daniel Neilson2018-01-191-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | attributes (Step 1) Summary: This is a resurrection of work first proposed and discussed in Aug 2015: http://lists.llvm.org/pipermail/llvm-dev/2015-August/089384.html and initially landed (but then backed out) in Nov 2015: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20151109/312083.html The @llvm.memcpy/memmove/memset intrinsics currently have an explicit argument which is required to be a constant integer. It represents the alignment of the dest (and source), and so must be the minimum of the actual alignment of the two. This change is the first in a series that allows source and dest to each have their own alignments by using the alignment attribute on their arguments. In this change we: 1) Remove the alignment argument. 2) Add alignment attributes to the source & dest arguments. We, temporarily, require that the alignments for source & dest be equal. For example, code which used to read: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 100, i32 4, i1 false) will now read call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %dest, i8* align 4 %src, i32 100, i1 false) Downstream users may have to update their lit tests that check for @llvm.memcpy/memmove/memset call/declaration patterns. The following extended sed script may help with updating the majority of your tests, but it does not catch all possible patterns so some manual checking and updating will be required. s~declare void @llvm\.mem(set|cpy|move)\.p([^(]*)\((.*), i32, i1\)~declare void @llvm.mem\1.p\2(\3, i1)~g s~call void @llvm\.memset\.p([^(]*)i8\(i8([^*]*)\* (.*), i8 (.*), i8 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.memset.p\1i8(i8\2* \3, i8 \4, i8 \5, i1 \6)~g s~call void @llvm\.memset\.p([^(]*)i16\(i8([^*]*)\* (.*), i8 (.*), i16 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.memset.p\1i16(i8\2* \3, i8 \4, i16 \5, i1 \6)~g s~call void @llvm\.memset\.p([^(]*)i32\(i8([^*]*)\* (.*), i8 (.*), i32 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.memset.p\1i32(i8\2* \3, i8 \4, i32 \5, i1 \6)~g s~call void @llvm\.memset\.p([^(]*)i64\(i8([^*]*)\* (.*), i8 (.*), i64 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.memset.p\1i64(i8\2* \3, i8 \4, i64 \5, i1 \6)~g s~call void @llvm\.memset\.p([^(]*)i128\(i8([^*]*)\* (.*), i8 (.*), i128 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.memset.p\1i128(i8\2* \3, i8 \4, i128 \5, i1 \6)~g s~call void @llvm\.memset\.p([^(]*)i8\(i8([^*]*)\* (.*), i8 (.*), i8 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.memset.p\1i8(i8\2* align \6 \3, i8 \4, i8 \5, i1 \7)~g s~call void @llvm\.memset\.p([^(]*)i16\(i8([^*]*)\* (.*), i8 (.*), i16 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.memset.p\1i16(i8\2* align \6 \3, i8 \4, i16 \5, i1 \7)~g s~call void @llvm\.memset\.p([^(]*)i32\(i8([^*]*)\* (.*), i8 (.*), i32 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.memset.p\1i32(i8\2* align \6 \3, i8 \4, i32 \5, i1 \7)~g s~call void @llvm\.memset\.p([^(]*)i64\(i8([^*]*)\* (.*), i8 (.*), i64 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.memset.p\1i64(i8\2* align \6 \3, i8 \4, i64 \5, i1 \7)~g s~call void @llvm\.memset\.p([^(]*)i128\(i8([^*]*)\* (.*), i8 (.*), i128 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.memset.p\1i128(i8\2* align \6 \3, i8 \4, i128 \5, i1 \7)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i8\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i8 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.mem\1.p\2i8(i8\3* \4, i8\5* \6, i8 \7, i1 \8)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i16\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i16 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.mem\1.p\2i16(i8\3* \4, i8\5* \6, i16 \7, i1 \8)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i32\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i32 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.mem\1.p\2i32(i8\3* \4, i8\5* \6, i32 \7, i1 \8)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i64\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i64 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.mem\1.p\2i64(i8\3* \4, i8\5* \6, i64 \7, i1 \8)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i128\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i128 (.*), i32 [01], i1 ([^)]*)\)~call void @llvm.mem\1.p\2i128(i8\3* \4, i8\5* \6, i128 \7, i1 \8)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i8\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i8 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.mem\1.p\2i8(i8\3* align \8 \4, i8\5* align \8 \6, i8 \7, i1 \9)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i16\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i16 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.mem\1.p\2i16(i8\3* align \8 \4, i8\5* align \8 \6, i16 \7, i1 \9)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i32\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i32 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.mem\1.p\2i32(i8\3* align \8 \4, i8\5* align \8 \6, i32 \7, i1 \9)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i64\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i64 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.mem\1.p\2i64(i8\3* align \8 \4, i8\5* align \8 \6, i64 \7, i1 \9)~g s~call void @llvm\.mem(cpy|move)\.p([^(]*)i128\(i8([^*]*)\* (.*), i8([^*]*)\* (.*), i128 (.*), i32 ([0-9]*), i1 ([^)]*)\)~call void @llvm.mem\1.p\2i128(i8\3* align \8 \4, i8\5* align \8 \6, i128 \7, i1 \9)~g The remaining changes in the series will: Step 2) Expand the IRBuilder API to allow creation of memcpy/memmove with differing source and dest alignments. Step 3) Update Clang to use the new IRBuilder API. Step 4) Update Polly to use the new IRBuilder API. Step 5) Update LLVM passes that create memcpy/memmove calls to use the new IRBuilder API, and those that use use MemIntrinsicInst::[get|set]Alignment() to use getDestAlignment() and getSourceAlignment() instead. Step 6) Remove the single-alignment IRBuilder API for memcpy/memmove, and the MemIntrinsicInst::[get|set]Alignment() methods. Reviewers: pete, hfinkel, lhames, reames, bollu Reviewed By: reames Subscribers: niosHD, reames, jholewinski, qcolombet, jfb, sanjoy, arsenm, dschuff, dylanmckay, mehdi_amini, sdardis, nemanjai, david2050, nhaehnle, javed.absar, sbc100, jgravelle-google, eraman, aheejin, kbarton, JDevlieghere, asb, rbar, johnrusso, simoncook, jordy.potman.lists, apazos, sabuasal, llvm-commits Differential Revision: https://reviews.llvm.org/D41675 llvm-svn: 322965
* [hwasan] LLVM-level flags for linux kernel-compatible hwasan instrumentation.Evgeniy Stepanov2018-01-171-0/+27
| | | | | | | | | | | | | | | | Summary: -hwasan-mapping-offset defines the non-zero shadow base address. -hwasan-kernel disables calls to __hwasan_init in module constructors. Unlike ASan, -hwasan-kernel does not force callback instrumentation. This is controlled separately with -hwasan-instrument-with-calls. Reviewers: kcc Subscribers: srhines, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D42141 llvm-svn: 322785
* [hwasan] Rename sized load/store callbacks to be consistent with ASan.Evgeniy Stepanov2018-01-162-10/+10
| | | | | | | | | | | | Summary: __hwasan_load is now __hwasan_loadN. Reviewers: kcc Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D42138 llvm-svn: 322601
* [hwasan] An LLVM flag to disable stack tag randomization.Evgeniy Stepanov2018-01-131-0/+7
| | | | | | | | | | | | Summary: Necessary to achieve consistent test results. Reviewers: kcc, alekseyshl Subscribers: kubamracek, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D42023 llvm-svn: 322429
* [hwasan] Stack instrumentation.Evgeniy Stepanov2018-01-111-0/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Very basic stack instrumentation using tagged pointers. Tag for N'th alloca in a function is built as XOR of: * base tag for the function, which is just some bits of SP (poor man's random) * small constant which is a function of N. Allocas are aligned to 16 bytes. On every ReturnInst allocas are re-tagged to catch use-after-return. This implementation has a bunch of issues that will be taken care of later: 1. lifetime intrinsics referring to tagged pointers are not recognized in SDAG. This effectively disables stack coloring. 2. Generated code is quite inefficient. There is one extra instruction at each memory access that adds the base tag to the untagged alloca address. It would be better to keep tagged SP in a callee-saved register and address allocas as an offset of that XOR retag, but that needs better coordination between hwasan instrumentation pass and prologue/epilogue insertion. 3. Lifetime instrinsics are ignored and use-after-scope is not implemented. This would be harder to do than in ASan, because we need to use a differently tagged pointer depending on which lifetime.start / lifetime.end the current instruction is dominated / post-dominated. Reviewers: kcc, alekseyshl Subscribers: srhines, kubamracek, javed.absar, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D41602 llvm-svn: 322324
* [hwasan] Implement -fsanitize-recover=hwaddress.Evgeniy Stepanov2017-12-202-37/+74
| | | | | | | | | | | | Summary: Very similar to AddressSanitizer, with the exception of the error type encoding. Reviewers: kcc, alekseyshl Subscribers: cfe-commits, kubamracek, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D41417 llvm-svn: 321203
* [hwasan] Inline instrumentation & fixed shadow.Evgeniy Stepanov2017-12-133-31/+347
| | | | | | | | | | | | Summary: This brings CPU overhead on bzip2 down from 5.5x to 2x. Reviewers: kcc, alekseyshl Subscribers: kubamracek, hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D41137 llvm-svn: 320538
* Hardware-assisted AddressSanitizer (llvm part).Evgeniy Stepanov2017-12-092-0/+216
Summary: This is LLVM instrumentation for the new HWASan tool. It is basically a stripped down copy of ASan at this point, w/o stack or global support. Instrumenation adds a global constructor + runtime callbacks for every load and store. HWASan comes with its own IR attribute. A brief design document can be found in clang/docs/HardwareAssistedAddressSanitizerDesign.rst (submitted earlier). Reviewers: kcc, pcc, alekseyshl Subscribers: srhines, mehdi_amini, mgorny, javed.absar, eraman, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D40932 llvm-svn: 320217
OpenPOWER on IntegriCloud