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 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 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