|
22 | 22 | #include "llvm/ADT/StringExtras.h"
|
23 | 23 | #include "llvm/ADT/StringRef.h"
|
24 | 24 | #include "llvm/Support/Endian.h"
|
25 |
| -#include "llvm/Support/Format.h" |
26 |
| -#include "llvm/Support/LogicalResult.h" |
27 | 25 | #include "llvm/Support/MemoryBufferRef.h"
|
28 | 26 | #include "llvm/Support/SourceMgr.h"
|
29 | 27 |
|
@@ -296,12 +294,38 @@ class EncodingReader {
|
296 | 294 | if (failed(parseVarInt(alignment)))
|
297 | 295 | return failure();
|
298 | 296 |
|
299 |
| - // Check that the requested alignment is less than or equal to the |
300 |
| - // alignment of the root buffer. If it is not, we cannot safely guarantee |
301 |
| - // that the specified alignment is globally correct. |
| 297 | + // Check that the requested alignment must not exceed the alignment of |
| 298 | + // the root buffer itself. Otherwise we cannot guarantee that pointers |
| 299 | + // derived from this buffer will actually satisfy the requested alignment |
| 300 | + // globally. |
302 | 301 | //
|
303 |
| - // E.g. if the buffer is 8k aligned and the section is 16k aligned, |
304 |
| - // we could end up at an offset of 24k, which is not globally 16k aligned. |
| 302 | + // Consider a bytecode buffer that is guaranteed to be 8k aligned, but not |
| 303 | + // 16k aligned (e.g. absolute address 40960. If a section inside this |
| 304 | + // buffer declares a 16k alignment requirement, two problems can arise: |
| 305 | + // |
| 306 | + // (a) If we "align forward" the current pointer to the next |
| 307 | + // 16k boundary, the amount of padding we skip depends on the |
| 308 | + // buffer's starting address. For example: |
| 309 | + // |
| 310 | + // buffer_start = 40960 |
| 311 | + // next 16k boundary = 49152 |
| 312 | + // bytes skipped = 49152 - 40960 = 8192 |
| 313 | + // |
| 314 | + // This leaves behind variable padding that could be misinterpreted |
| 315 | + // as part of the next section. |
| 316 | + // |
| 317 | + // (b) If we align relative to the buffer start, we may |
| 318 | + // obtain addresses that are multiples of "buffer_start + |
| 319 | + // section_alignment" rather than truly globally aligned |
| 320 | + // addresses. For example: |
| 321 | + // |
| 322 | + // buffer_start = 40960 (5×8k, 8k aligned but not 16k) |
| 323 | + // offset = 16384 (first multiple of 16k) |
| 324 | + // section_ptr = 40960 + 16384 = 57344 |
| 325 | + // |
| 326 | + // 57344 is 8k aligned but not 16k aligned. |
| 327 | + // Any consumer expecting true 16k alignment would see this as a |
| 328 | + // violation. |
305 | 329 | if (failed(alignmentValidator(alignment)))
|
306 | 330 | return emitError("failed to align section ID: ", unsigned(sectionID));
|
307 | 331 |
|
|
0 commit comments