1 // SPDX-License-Identifier: GPL-2.0-only
2 #ifndef _GNU_SOURCE
3 #define _GNU_SOURCE
4 #endif
5 #include <link.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 struct Statistics {
10 unsigned long long load_address;
11 unsigned long long alignment;
12 };
13
ExtractStatistics(struct dl_phdr_info * info,size_t size,void * data)14 int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data)
15 {
16 struct Statistics *stats = (struct Statistics *) data;
17 int i;
18
19 if (info->dlpi_name != NULL && info->dlpi_name[0] != '\0') {
20 // Ignore headers from other than the executable.
21 return 2;
22 }
23
24 stats->load_address = (unsigned long long) info->dlpi_addr;
25 stats->alignment = 0;
26
27 for (i = 0; i < info->dlpi_phnum; i++) {
28 if (info->dlpi_phdr[i].p_type != PT_LOAD)
29 continue;
30
31 if (info->dlpi_phdr[i].p_align > stats->alignment)
32 stats->alignment = info->dlpi_phdr[i].p_align;
33 }
34
35 return 1; // Terminate dl_iterate_phdr.
36 }
37
main(int argc,char ** argv)38 int main(int argc, char **argv)
39 {
40 struct Statistics extracted;
41 unsigned long long misalign;
42 int ret;
43
44 ret = dl_iterate_phdr(ExtractStatistics, &extracted);
45 if (ret != 1) {
46 fprintf(stderr, "FAILED\n");
47 return 1;
48 }
49
50 if (extracted.alignment == 0) {
51 fprintf(stderr, "No alignment found\n");
52 return 1;
53 } else if (extracted.alignment & (extracted.alignment - 1)) {
54 fprintf(stderr, "Alignment is not a power of 2\n");
55 return 1;
56 }
57
58 misalign = extracted.load_address & (extracted.alignment - 1);
59 if (misalign) {
60 printf("alignment = %llu, load_address = %llu\n",
61 extracted.alignment, extracted.load_address);
62 fprintf(stderr, "FAILED\n");
63 return 1;
64 }
65
66 fprintf(stderr, "PASS\n");
67 return 0;
68 }
69